簡體   English   中英

XNA:Basic DrawableGameComponent覆蓋未調用的函數(Update,Draw等)

[英]XNA: Basic DrawableGameComponent override functions (Update, Draw, etc) not being called

我試圖通過讓他們擴展Mircosoft.Xna.Framework.GameCompenent來封裝我的游戲對象,然后僅構建它們並在Game1的Update()方法中管理它們。 我有我的Game1類,Player類和Animation類。 假設動畫管理對象的Texture2D更改,在此實例中為Player。

我的問題是,即使我已經成功擴展了所有內容,沒有語法錯誤,沒有拋出異常,並且已經檢查並重新檢查了我編寫的代碼,否則不會調用覆蓋函數,最終會出現黑屏。

Game1.cs :(注意改變的只有兩行是Player聲明)

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更新過程自然調用。

那么......這是為什么?

您需要將游戲組件添加到組件集合中以自動調用它們

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM