将 Draw() 代码移动到 Class

Moving Draw() code to a Class

我正在用 monogame 创建一个游戏,我在我的游戏中的 Draw() 函数中加载了图块,如下所示:

protected override void Draw(GameTime gameTime)
{
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin();   
        spriteBatch.Draw(danChar, charPosition, Color.White);

        // loop below loads the 'grass' tiles only

        // assuming gameworld size of 770x450
        for (int i = 0; i < 770; i += 31) // adds 31 to i (per tile)
        {
            position = new Vector2(i, 392); // places incrementation into vector position
            spriteBatch.Draw(gameTile, position, Color.White); // draws the tile each time
            if (i == 744)
            {
                i = i + 26; // fills last space between 744 and 770
                position = new Vector2(i, 392);
            }
            spriteBatch.Draw(gameTile, position, Color.White); 
        }

        // loop below loads the brick tiles only (ones without grass)

        spriteBatch.End();  // ends the spriteBatch call
        base.Draw(gameTime);
}

不过,我更希望这是一个单独的 class 而不是直接放入绘制函数中,但是我不太确定如何执行此操作,如有任何帮助,我将不胜感激。

提前致谢!

如果您只想将代码原样移动到另一个 class,请创建您的 class(例如 GameWorld 似乎适合您的代码)

public class GameWorld
{
    // You may wish to move your gameTile definition into this class if it is the only
    // class that uses it, and handle the content loading for it in here.
    // e.g. if you're currently loading the texture in the LoadContent method in your game
    // class, create a LoadContent method here and pass in ContentManger as a parameter.
    // I've passed in the texture as a parameter to the Draw method in this example to
    // simplify as I'm not sure how you're managing your textures.

    public void Draw(SpriteBatch spriteBatch, GameTime gameTime, Texture2D gameTile)
    {
        // loop below loads the 'grass' tiles only

        // assuming gameworld size of 770x450
        for (int i = 0; i < 770; i += 31) // adds 31 to i (per tile)
        {
            Vector2 position = new Vector2(i, 392); // places incrementation into vector position
            spriteBatch.Draw(gameTile, position, Color.White); // draws the tile each time
            if (i == 744)
            {
                i = i + 26; // fills last space between 744 and 770
                position = new Vector2(i, 392);
            }
            spriteBatch.Draw(gameTile, position, Color.White); 
        }

        // loop below loads the brick tiles only (ones without grass)   
    }
}

然后 Game class 中的 Draw 方法看起来像

protected override void Draw(GameTime gameTime)
{
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin();   
        spriteBatch.Draw(danChar, charPosition, Color.White);

        // Assuming you've created/loaded an instance of the GameWorld class
        // called gameWorld in Initialize/LoadContent
        gameWorld.Draw(spriteBatch, gameTime, gameTile);

        spriteBatch.End();  // ends the spriteBatch call
        base.Draw(gameTime);
}

只需确保您以正确的顺序调用 Draw 方法。例如您希望您的播放器出现在任何背景图块上方。

我相信默认的 SpriteSortModeDeferred,它按照调用的顺序绘制(即从后到前)。

如果需要,您可以在对 spriteBatch.Begin() 的调用中指定不同的 SpriteSortMode,但对于简单的游戏,只需移动 Draw 调用即可。

有关 SpriteSortMode 的更多信息,如有需要,请访问 MSDN

同样,如果您愿意,您可以将 UpdateLoadContent 方法链接到这些 class 中,确保传入任何您需要的参数作为参数。

更新:

要将 gameWorld 定义为 GameWorld class 的实例,您将其定义在游戏顶部附近 class,然后通常在 Initialize方法。

所以你的游戏 class 看起来像

public class MyGameName : Microsoft.Xna.Framework.Game
{
    private SpriteBatch spriteBatch;
    // other variable declarations

    // Add a declaration for gameWorld
    private GameWorld gameWorld;

    protected override Initialize()
    {
        // Add the following line to initialize your gameWorld instance
        gameWorld = new GameWorld();
    }

    // other existing code - your LoadContent, Update, Draw methods etc.
}