Monogame多个对象相同的动画

时间:2017-10-23 17:15:57

标签: c# animation sprite monogame

正如标题所说,我正在尝试用Monogame制作游戏,这是一个炸弹人克隆,但是当我试图产生更多炸弹时,动画只会移动到新位置。游戏对象保持原样,但它没有动画。我认为问题是它加载了已加载的相同动画,但我似乎无法弄清楚如何在每次炸弹产生时生成一个新动画。 我使用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();
    }
}

}

1 个答案:

答案 0 :(得分:0)

问题出在这个部分:

protected Dictionary<string, Animation> _animations;

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

执行成员克隆时,它会创建一个浅表副本,重用对引用类型对象的现有引用。这意味着克隆将与原始对象共享相同的动画状态。

对此的解决方案是每次要克隆Bomb时实例化所有动画的新副本。

这样的事情:

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;
}