2010-08-22 3 views
4

J'essaye d'encapsuler mes objets de jeu en leur faisant étendre Mircosoft.Xna.Framework.GameCompenent, puis en les construisant et en les gérant dans la mise à jour() méthode de Game1. J'ai ma classe Game1, une classe Player et une classe Animation. Les animations sont supposées gérer les changements Texture2D d'un objet, dans ce cas-là Player. Mon problème est que même si j'ai réussi à tout étendre, ne pas avoir d'erreurs de syntaxe, aucune exception levée, et avoir vérifié et revérifié le peu de code que j'ai écrit, les fonctions de remplacement ne sont pas appelées et je me retrouve avec un écran noir.XNA: Les fonctions de remplacement DrawableGameComponent de base (Update, Draw, etc) ne sont pas appelées

Game1.cs: (notez que les deux seules lignes modifiées sont la déclaration du joueur)

public class Game1 : Microsoft.Xna.Framework.Game 
{ 
    GraphicsDeviceManager graphics; 
    SpriteBatch spriteBatch; 

    Player player; 

    public Game1() 
    { 
     graphics = new GraphicsDeviceManager(this); 
     Content.RootDirectory = "Content"; 
    } 

    protected override void Initialize() 
    { 
     player = new Player(this); 

     base.Initialize(); 
    } 

    protected override void LoadContent() 
    { 
     spriteBatch = new SpriteBatch(GraphicsDevice); 
    } 

    protected override void UnloadContent() 
    { 

    } 

    protected override void Update(GameTime gameTime) 
    { 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 

     // TODO: Add your update logic here 

     base.Update(gameTime); 
    } 

    protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.Black); 
     base.Draw(gameTime); 
    } 
} 

Player.cs:

class Player : Microsoft.Xna.Framework.DrawableGameComponent 
{ 
    Rectangle bounds; 
    Texture2D t; 
    Animation[] animations = new Animation[4]; 
    String path = @"..\..\..\Content\player.png"; 

    #region Animation Constants 
    private const int WALK_RIGHT = 0; 
    #endregion 

    SpriteBatch spriteBatch; 

    public Player(Game game) : base(game) 
    { 
     //should only ever be one player, all value defaults set in Initialize() 
    } 

    public Texture2D T 
    { 
     get { return t; } 
    } 

    public Rectangle Bounds 
    { 
     get { return bounds; } 
    } 

    public override void Initialize() 
    { 
     base.Initialize(); 

     bounds = new Rectangle(0, 0, 
      System.Drawing.Image.FromFile(path).Width, 
      System.Drawing.Image.FromFile(path).Height 
     ); 

     t = Game.Content.Load<Texture2D>("player"); 
     animations[0] = new Animation(this.Game, "player", "walking", 3); 
    } 

    protected override void LoadContent() 
    { 
     base.LoadContent(); 

     spriteBatch = new SpriteBatch(this.Game.GraphicsDevice); 
    } 

    public override void Update(GameTime gameTime) 
    { 
     base.Update(gameTime); 

     KeyboardState k = Keyboard.GetState(); 

     if (k.IsKeyDown(Keys.Right)) //walk right 
     { 
      bounds.X += 3; 
      if (animations[WALK_RIGHT].Playing) 
      { 
       t = animations[WALK_RIGHT].getTexture(); 
      } 
      else 
      { 
       animations[WALK_RIGHT].Play(); 
      } 
     } 
     else if (animations[WALK_RIGHT].Playing) 
      animations[WALK_RIGHT].Stop(); 

    } 

    public override void Draw(GameTime gameTime) 
    { 
     base.Draw(gameTime); 

     spriteBatch.Begin(); 
     spriteBatch.Draw(t, bounds, Color.White); 
     spriteBatch.End(); 
    } 
} 

Animation.cs:

class Animation : Microsoft.Xna.Framework.GameComponent 
{ 
    Game game; 
    String name; //name of default sprite; standing, unmoving, neutral, etc. The rest of the animation sprite names should derive from this 
    String keyword; 
    int frameCount; 
    int delay; //frames between texture change 


    String[] paths; //texture pathnames generated by the MakePaths() function 
    int currentFrame = 0; 
    int delayCount = 0; 
    bool playing = false; 

    public Animation(Game associatedGame, String nameVal, String keywordVal, int frameCountVal) 
     : base(associatedGame) 
    { 
     name = nameVal; 
     keyword = keywordVal; 
     frameCount = frameCountVal; 
     paths = MakePaths(); 
     delay = 10; 
    } 

    public Animation(Game associatedGame, String nameVal, String keywordVal, int frameCountVal, int delayVal) 
     : base(associatedGame) 
    { 
     name = nameVal; 
     keyword = keywordVal; 
     frameCount = frameCountVal; 
     paths = MakePaths(); 
     delay = delayVal; 
    } 

    private String[] MakePaths() 
    { 
     //format: name_keyword_anim[i] 
     //format example: player_walking_anim1 

     String[] temp = new String[frameCount]; 
     for (int i = 0; i < frameCount; i++) 
     { 
      temp[i] = name + "_" + keyword + "_" + "anim" + i.ToString(); 
     } 

     return temp; 
    } 

    public Texture2D getTexture() 
    { 
     return Game.Content.Load<Texture2D>(paths[currentFrame]); 
    } 

    public void Play() 
    { 
     playing = true; 
    } 

    public void Stop() 
    { 
     currentFrame = 0; 
     delayCount = 0; 
     playing = false; 
    } 

    public bool Playing 
    { 
     get { return playing; } 
    } 

    public override void Update(GameTime gameTime) 
    { 
     if (playing) 
     { 
      if (delayCount == delay) 
      { 
       delayCount = 0; 

       if ((currentFrame + 1) == frameCount) currentFrame = 0; 
       else currentFrame++; 
      } 
      else delayCount++; 
     } 
     base.Update(gameTime); 
    } 

    public override string ToString() 
    { 
     return "params: " + name + "," + keyword + "," + frameCount.ToString() + "\nUsing paths: " + paths; 
    } 
} 

Les seules méthodes LoadContent, Initialize, Update et Draw qui sont appelées sont celles de Game1. Ce qui me déconcerte vraiment, c'est que j'ai pu utiliser cette technique auparavant sans problème. Ces fonctions seraient appelées naturellement par le processus de mise à jour Xna.

Alors ... pourquoi est-ce?

+1

trop de code, trop laborieux à lire. Fournissez un petit exemple isolé de votre problème. – Timwi

Répondre

14

Vous devez ajouter le jeu de composants à la collection des composants pour les ont appelé automatiquement

protected override void Initialize() 
{ 
    player = new Player(this); 
    Components.Add(player); 

    base.Initialize(); 
} 

Voir http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.game.components.aspx

+0

Désolé pour la grande quantité de code, je n'étais pas sûr de ce qui pourrait être le problème. Je suppose que j'aurais pu poster seulement les parties Update, Draw, etc., mais cela aurait encore été beaucoup de code ... Quoi qu'il en soit, merci pour la réponse. Cela a fonctionné sans problème. –

Questions connexes