玩家移动时纹理保持原位
Texture stays in place while player moves
你好Whosebug!
我正在使用 MonoGame 在 C# 中开发一款 2D sidescroller 冒险游戏,我遇到了一个特殊问题。
简而言之:Player 实例已经分配了一个包含玩家纹理的 Texture2D(在这个例子中是一个带有 2px 绿色边框的蓝色框)
当玩家移动时,纹理 "stays in place" 和玩家离开纹理所在的 space 时逐渐变为绿色。
这当然不应该发生,因为纹理应该在每次调用 Draw() 时在 Player 的确切位置重新绘制。
换句话说 - 玩家无论移动到哪里都应该仍然是一个带有 2px 绿色边框的蓝色框。
为了更好地说明图片:
原始状态
玩家向下移动,留下纹理。
直到他完全变绿
当他回到原来的位置时,正确的纹理再次开始显示
我已将代码缩减到最基本的部分,但问题仍然存在。
Game.cs没有什么有趣的东西,Player初始化和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);
}
}
这就是全部代码。老实说,我没有想法。
这是有问题的行:
spriteBatch.Draw(Texture, position, new Rectangle((int)Position.X, (int)Position.Y, Width, Height), Color.White);
第三个参数(矩形)定义绘制纹理的哪一部分。而且你总是想绘制纹理的相同部分,因此你应该传递一个常量矩形。
实际上,如果你只是想绘制整个纹理,通过null
:
spriteBatch.Draw(Texture, position, null, Color.White);
你好Whosebug!
我正在使用 MonoGame 在 C# 中开发一款 2D sidescroller 冒险游戏,我遇到了一个特殊问题。
简而言之:Player 实例已经分配了一个包含玩家纹理的 Texture2D(在这个例子中是一个带有 2px 绿色边框的蓝色框) 当玩家移动时,纹理 "stays in place" 和玩家离开纹理所在的 space 时逐渐变为绿色。 这当然不应该发生,因为纹理应该在每次调用 Draw() 时在 Player 的确切位置重新绘制。
换句话说 - 玩家无论移动到哪里都应该仍然是一个带有 2px 绿色边框的蓝色框。
为了更好地说明图片:
原始状态
玩家向下移动,留下纹理。
直到他完全变绿
当他回到原来的位置时,正确的纹理再次开始显示
我已将代码缩减到最基本的部分,但问题仍然存在。
Game.cs没有什么有趣的东西,Player初始化和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);
}
}
这就是全部代码。老实说,我没有想法。
这是有问题的行:
spriteBatch.Draw(Texture, position, new Rectangle((int)Position.X, (int)Position.Y, Width, Height), Color.White);
第三个参数(矩形)定义绘制纹理的哪一部分。而且你总是想绘制纹理的相同部分,因此你应该传递一个常量矩形。
实际上,如果你只是想绘制整个纹理,通过null
:
spriteBatch.Draw(Texture, position, null, Color.White);