我在读取带有行和列的spritesheet时遇到了困难。如果它只是一行,那么我的代码可以正常工作。这张纸是这样的:
现在,它只适用于第一行。我想不出怎么把它移到下一行去。我知道我必须把我的SourceRect
换成x
和y
,但不知道是什么。
这是我的密码:
class SpriteSheet
{
public Texture2D Texture { get; set; }
public Vector2 Origin { get; set; }
public Rectangle SourceRect { get; set; }
public Vector2 position;
private float timer, interval;
private int currentFrame;
private int spriteWidth, spriteHeight, spriteSpeed;
private int rows, columns;
private KeyboardState currentKBState, previousKBState;
public SpriteSheet(Texture2D texture, int spriteWidth, int spriteHeight, int rows = 1, int columns = 0, int currentFrame = 1)
{
Texture = texture;
this.currentFrame = currentFrame;
this.spriteWidth = spriteWidth;
this.spriteHeight = spriteHeight;
this.rows = rows;
this.columns = columns;
spriteSpeed = 100;
interval = 200;
}
// Handle movement of sprite
public void Update(GameTime gameTime)
{
previousKBState = currentKBState;
currentKBState = Keyboard.GetState();
// Get the sprite from the sheet
// THIS LINE NEEDS TO BE CHANGED I THINK
SourceRect = new Rectangle(currentFrame * spriteWidth, 0, spriteWidth, spriteHeight);
if(currentKBState.GetPressedKeys().Length == 0)
{
if (currentFrame > 0 && currentFrame < 9)
currentFrame = 0;
if (currentFrame > 9 && currentFrame < 18)
currentFrame = 9;
if (currentFrame > 18 && currentFrame < 27)
currentFrame = 18;
if (currentFrame > 27 && currentFrame < 36)
currentFrame = 27;
}
// Animate Up
if (currentKBState.IsKeyDown(Keys.Up))
{
AnimateUp(gameTime);
// Check boundary
if (position.Y > 25)
position.Y -= (float) (spriteSpeed * gameTime.ElapsedGameTime.TotalSeconds);
}
}
private void AnimateUp(GameTime gameTime)
{
if (currentKBState != previousKBState)
currentFrame = 1;
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
if(timer > interval)
{
currentFrame++;
if (currentFrame > 8)
currentFrame = 0;
timer = 0f;
}
}
}
发布于 2016-08-07 07:49:57
你的y坐标总是0,所以只使用第一行.您需要更改这一行:
SourceRect = new Rectangle(currentFrame * spriteWidth, 0, spriteWidth, spriteHeight);
如下所示(参见第二个参数):
SourceRect = new Rectangle(currentFrame * spriteWidth, wantedRow * spriteHeight, spriteWidth, spriteHeight);
发布于 2016-08-07 18:15:18
因此,我对代码做了一些修改,以使其工作:
构造函数更改:
public SpriteSheet(Texture2D texture, int rows = 1, int columns = 0, int currentFrame = 0)
{
this.texture = texture;
this.sheetRows = rows;
this.sheetColumns = columns;
// Default = top left
this.currentFrame = currentFrame;
// Get a single sprite's width and height
sheetWidth = texture.Width / sheetColumns;
sheetHeight = texture.Height / sheetRows;
}
我注意到我不需要手动提供雪碧的width
和height
,我可以从雪碧表中得到它。我现在在移动方法中处理spriteSpeed
和interval
,而不是构造函数。
我将SourceRect
行从Update
方法中移除,并将其移动到自定义的Draw
方法中:
public void Draw(SpriteBatch spriteBatch)
{
// Get the correct frame
spriteRow = currentFrame / sheetColumns;
spriteColumn = currentFrame % sheetColumns;
sourceRect = new Rectangle(sheetWidth * spriteColumn, sheetHeight * spriteRow, sheetWidth, sheetHeight);
origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);
spriteBatch.Draw(texture: texture, sourceRectangle: sourceRect, position: position, origin: origin, scale: new Vector2(1.0f));
}
最后,获得雪碧的row
和column
变得更加容易,只要稍微划分一下。
如果我想要row 3
和column 1
,currentFrame
就是18
。知道了这一点,修复代码中没有按键的地方重置currentFrame
的部分是非常简单的。
https://gamedev.stackexchange.com/questions/127767
复制相似问题