玩家移动时纹理保持不变

时间:2016-11-25 22:35:47

标签: c# textures monogame texture2d

Hello stackoverflow!

我正在使用MonoGame在C#上制作2D sidescroller冒险游戏,我遇到了一个特殊的问题。

简而言之:玩家实例已经指定了一个包含玩家纹理的Texture2D(在本例中是一个带有2px绿色边框的蓝色框) 当玩家移动时,纹理“保持原位”,当玩家离开纹理所在的空间时,玩家逐渐变为绿色。 这当然不应该发生,因为每次调用Draw()时都应该在Player的确切位置重新绘制纹理。

换句话说 - 无论移动到哪里,玩家仍然应该是一个带有2px绿色边框的蓝框。

图片以便更好地说明:

原始状态

original state

玩家向下移动,留下纹理。

player moves downward, leaving texture behind

continuation of the same thing

直到他完全变绿。

player fell down and is green

当他回到原来的位置时,正确的纹理再次开始显示

player returns to original position and turns blue again

我已经将代码减少到它的骨干,但问题仍然存在。

Game.cs没有任何有趣的内容,播放器初始化和Draw方法在这里:

//inside of Initialize()
player = new Player(GraphicsDevice, Vector2.Zero);


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

        levelSpriteBatch.Begin();
        player.Draw(gameTime, levelSpriteBatch);
        levelSpriteBatch.End();

        base.Draw(gameTime);
    }

Player.cs(整个文件):

    class Player {
        public Vector2 Position
        {
            get { return position; }
        }
        Vector2 position;

    public Texture2D Texture { get; private set; }

    public const int Width = 32;
    public const int Height = 32;

    // Input configuration
    private const Keys leftButton = Keys.A;
    private const Keys rightButton = Keys.D;
    private const Keys upButton = Keys.W;
    private const Keys downButton = Keys.S;


    //Current state
    private float LRmovement;
    private float UDmovement;

    public Player(GraphicsDevice graphicsDevice, Vector2 position) {
        this.position = position;
        CreateTexture(graphicsDevice, Width, Height);
    }

    public void Update(GameTime gameTime, KeyboardState keyboardState) {
        GetInput(keyboardState);

        position.X += LRmovement;
        position.Y += UDmovement;

        LRmovement = 0.0f;
        UDmovement = 0.0f;
    }

    private void CreateTexture(GraphicsDevice graphicsDevice, int width, int height) {
        Texture = new Texture2D(graphicsDevice, width, height);

        GraphicsHelper.FillRectangle(Texture, Color.Red);
        GraphicsHelper.OutlineRectangle(Texture, Color.Green, 2);
    }

    private void GetInput(KeyboardState keyboardState) {
        LRmovement = 0;
        UDmovement = 0;

        if (Math.Abs(LRmovement) < 0.5f)
            LRmovement = 0.0f;

        if (Math.Abs(UDmovement) < 0.5f)
            UDmovement = 0.0f;

        if (keyboardState.IsKeyDown(leftButton))
            LRmovement = -1.0f;
        else if (keyboardState.IsKeyDown(rightButton))
            LRmovement = 1.0f;

        if (keyboardState.IsKeyDown(upButton))
            UDmovement = -1.0f;
        else if (keyboardState.IsKeyDown(downButton))
            UDmovement = 1.0f;
    }

    public void Draw(GameTime gameTime, SpriteBatch spriteBatch) {
        spriteBatch.Draw(Texture, position, new Rectangle((int)Position.X, (int)Position.Y, Width, Height), Color.White);
    }
}

和GraphicsHelper.cs:

class GraphicsHelper {
    public static void FillRectangle(Texture2D texture, Color fill) {
        Color[] color = new Color[texture.Width * texture.Height];
        texture.GetData(color);

        for (int i = 0; i < texture.Width * texture.Height; ++i)
            color[i] = fill;

        texture.SetData(color);
    }

    public static void OutlineRectangle(Texture2D texture, Color outline, int outlineWidth) {
        Color[] color = new Color[texture.Width * texture.Height];
        texture.GetData(color);

        int index = 0;
        for (int y = 0; y < texture.Height; ++y) {
            for (int x = 0; x < texture.Width; ++x) {
                if (y < outlineWidth || x < outlineWidth || y > texture.Height - outlineWidth || x > texture.Width - outlineWidth)
                    color[index] = outline;
                ++index;
            }
        }
        texture.SetData(color);
    }
}

这是所有代码。说实话,我真的没有想法。

1 个答案:

答案 0 :(得分:2)

这是有问题的一行:

spriteBatch.Draw(Texture, position, new Rectangle((int)Position.X, (int)Position.Y, Width, Height), Color.White);

第三个参数(矩形)定义要绘制的纹理部分。而你总是想要绘制纹理的相同部分,因此你应该传递一个恒定的矩形。

实际上,如果您只想绘制整个纹理,请传递null

spriteBatch.Draw(Texture, position, null, Color.White);