2010-08-22 27 views
4

我試圖通過讓他們擴展Mircosoft.Xna.Framework.GameCompenent封裝我的遊戲對象,然後只是構造它們並在更新中管理它們()方法。我有我的Game1類,一個Player類和一個Animation類。假定動畫管理對象的Texture2D變化,在這個例子中是Player。XNA:基本DrawableGameComponent重寫函數(更新,繪製等)不被稱爲

我的問題是,即使我已經成功地擴展了所有內容,沒有語法錯誤,沒有拋出任何異常,並且檢查並重新檢查了我寫的小代碼,但是不會調用覆蓋函數,一個黑色的屏幕。

Game1.cs:(請注意,只有兩行改變是玩家聲明)

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

被調用的唯一LoadContent,Initialize,Update和Draw方法是Game1中的。讓我感到困惑的是我能夠在沒有問題之前使用這種技術。 Xna更新過程自然會調用這些函數。

那麼......這是爲什麼?

+1

代碼太多,太費力閱讀。提供一個小而孤立的問題例子。 – Timwi 2010-08-22 03:07:31

回答

14

你需要遊戲組件添加到Components集合,讓他們自動

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

    base.Initialize(); 
} 

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

+0

對不起,大量的代碼,我只是不知道可能是什麼問題。我想我可以只發布更新,繪製等部分,但仍然會有很多代碼... 無論如何,感謝您的答案。它工作沒有問題。 – 2010-08-22 15:41:30