簡體   English   中英

Monogame多個對象相同的動畫

[英]Monogame multiple objects same animation

就像tittle所說的那樣,我正在嘗試在Bomberman克隆版Monogame中制作游戲,但是當我嘗試生成多於一枚炸彈的atm時,動畫就會移動到新位置。 游戲對象停留在應有的位置,但沒有動畫。 我認為問題在於它加載的是與已加載的動畫相同的動畫,但是我似乎無法弄清楚每次炸彈產生時如何使其生成新動畫。 我使用Content.Load來獲取sorite動畫,並使用帶有該動畫的clone()函數生成炸彈。

var bombAni = new Dictionary<string, Animation>() {
            {"Bomb", new Animation(Content.Load<Texture2D>("Obstacle/Bomb"), 3) },
        };

        _sprites = new List<Sprite>() {

            new Player(animations) {
                _bomb = new Bomb(bombAni),
                Position = new Vector2(32, 32),
                Input = new Input() {
                    Up = Keys.W,
                    Down = Keys.S,
                    Left = Keys.A,
                    Right = Keys.D,
                    Space = Keys.Space,
                }
            }

        };

public void Play(Animation animation) {
        if (animation == _animation) {
            return;
        }

        _animation = animation;

        _animation.CurFrame = 0;

        _timer = 0;
    }

private void AddBomb(List<Sprite> sprites) {

        var bomb = _bomb.Clone() as Bomb;
        switch (_direction) {
            case "Up":
                bomb.Position = _position + new Vector2(0, -32);
                break;
            case "Down":
                bomb.Position = _position + new Vector2(0, 32);
                break;
            case "Left":
                bomb.Position = _position + new Vector2(-32, 0);
                break;
            case "Right":
                bomb.Position = _position + new Vector2(32, 0);
                break;
        }
        bomb.lifeSpan = 3f;
        bomb.Parent = this;
        bombCount++;

        sprites.Add(bomb);
    }

public Sprite(Dictionary<string, Animation> animations) {

        _animations = animations;
        _animationManager = new AnimationManager(_animations.First().Value);

    }


namespace CompetenceWeek.scripts {
public class Bomb : Sprite {

    public float lifeSpan;
    private float _timer;

    public Bomb(Dictionary<string, Animation> animations) : base(animations) {

    }

    public Bomb(Texture2D texture) : base(texture) {

    }


    public override void Update(GameTime gameTime, List<Sprite> sprites) {
        _timer += (float)gameTime.ElapsedGameTime.TotalSeconds;

        SetAnimations();

        _animationManager.Update(gameTime);

        if (_timer > lifeSpan) {
            isDead = true;
        }

    }

}

}

namespace CompetenceWeek.scripts {
public class Sprite : ICloneable {

    protected AnimationManager _animationManager;

    protected Dictionary<string, Animation> _animations;

    protected Vector2 _position;

    protected Texture2D _texture;

    public bool Walkable { get; set; } = false;

    public bool isDead = false;


    public Player Parent { get; set; }

    public Input Input;

    public Vector2 Position {
        get { return _position; }
        set {
            _position = value;

            if(_animationManager != null) {
                _animationManager.Posistion = _position;
            }
        }
    }

    public float Speed = 2.5f;

    public Vector2 Velocity;

    public virtual void Draw(SpriteBatch spriteBatch) {

        if(_texture != null) {
            spriteBatch.Draw(_texture, Position, Color.White);
        } else if (_animationManager != null) {
            _animationManager.Draw(spriteBatch);
        } else {
            throw new Exception("somthings not right");
        }


    }



    public Sprite(Dictionary<string, Animation> animations) {

        _animations = animations;
        _animationManager = new AnimationManager(_animations.First().Value);

    }

    public Sprite(Texture2D texture) {
        _texture = texture;
    }

    public virtual void Update(GameTime gameTime, List<Sprite> sprites) {
        SetAnimations();

        _animationManager.Update(gameTime);

        Position += Velocity;
        Velocity = Vector2.Zero;


    }

    protected virtual void SetAnimations() {
        if (Velocity.X > 0) {
            _animationManager.Play(_animations["PlayerRight"]);
        } else if (Velocity.X < 0) {
            _animationManager.Play(_animations["PlayerLeft"]);
        } else if (Velocity.Y > 0) {
            _animationManager.Play(_animations["PlayerDown"]);
        } else if (Velocity.Y < 0) {
            _animationManager.Play(_animations["PlayerUp"]);
        }
    }

    public object Clone() {
        return this.MemberwiseClone();
    }
}

}

問題在於此段:

protected Dictionary<string, Animation> _animations;

public object Clone() {
    return this.MemberwiseClone();
}

當執行成員克隆時,它將創建淺表副本,將現有引用重用到引用類型對象。 這意味着克隆將與原始對象共享相同的動畫狀態。

解決方案是,每當您要克隆炸彈時,都要實例化所有動畫的新副本。

像這樣:

public object Clone() {
    var bomb = (Bomb)this.MemberwiseClone();
    bomb.InitAnimations(new Dictionary<string, Animation>() {
        {"Bomb", new Animation(Content.Load<Texture2D>("Obstacle/Bomb"), 3) },
    };
    return bomb;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM