[英]Monogame and C#, loading multiple objects with same image into a list, all get same properties
[英]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.