2017-10-23 4 views
0

als der Titel sagen, ich versuche, ein Spiel in Monogame, ein Bomberman-Klon zu machen, aber atm, wenn ich versuche, mehr als eine Bombe spawn die Animation bewegt sich nur an den neuen Ort. Das Spielobjekt bleibt dort, wo es sein soll, aber es hat keine Animation. Ich denke, das Problem ist, dass es die gleiche Animation lädt, die geladen wurde, aber ich kann einfach nicht herausfinden, wie man eine neue Animation erzeugt, wenn eine Bombe auftaucht. Ich benutze Content.Load, um die sorite Animation zu erhalten und spawne die Bombe mit einer clone() Funktion mit der Animation.Monogame mehrere Objekte gleiche Animation

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

Können Sie mit uns den entsprechenden Code teilen? –

+0

Es ist jetzt da, sorry ersten Post hier ^^; –

+0

Können Sie den Code für Ihre Bomb-Klasse anzeigen? Es sieht so aus, dass Sie beim Klonen einer Bombe auf dieselbe Instanz der Animation verweisen wie die vorhandene Bombe. Dies ist eines der Probleme beim Flachklonen. –

Antwort

0

Das Problem bei diesem Segment ist:

protected Dictionary<string, Animation> _animations; 

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

Wenn Sie ein element Klon ausführen, erstellt es eine flache Kopie, vorhandene Referenzen Wiederverwendung zu Objekten vom Referenztyp. Dies bedeutet, dass der Klon denselben Animationszustand mit dem ursprünglichen Objekt teilt.

Die Lösung besteht darin, jedes Mal eine neue Kopie aller Animationen zu instanziieren, wenn Sie Bomb klonen möchten.

Etwas wie folgt aus:

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

Ja das ist, was ich auch though habe Aber ich kann anscheinend nicht auf Inhalt zugreifen.Load von jedem anderen Ort dann in der game.cs Klasse –

+0

In der Entwicklung mit MonoGame ausgiebig, haben wir festgestellt, dass es sehr nützlich ist, die Instanz zu machen Spiel verfügbar für andere Teile der Anwendung. Es gibt viele Möglichkeiten, dies zu tun. Die naive Implementierung ist nur im globalen Bereich verfügbar: https://github.com/EnigmaDragons/Astrocell/blob/master/MonoDragons.Core/Engine/GameInstance.cs Sie können Ihren Game-Instanzaufruf beim Start initialisieren lassen. –

+0

Okay, ich habe etwas Zeit gebraucht, um herauszufinden, was du mit der gameinstanz machst, aber ich habe es geschafft public override object Klonen() { var bomb = new Bomb (neues Wörterbuch () { {"Bomb", neue Animation (GameInstance.TheGame.Content.Load ("Hindernis/Bombe"), 3)}, }); Rückstoßbombe; } Vielen Dank für Ihre Hilfe! ^^ –

Verwandte Themen