I did some playing about and yea, I think your calculations for your sprite rectangle might be off. I’m using this code…
public class Game1 : Game
{
private const double SPRITE_FRAMERATE_PLAYER = 0.5;
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
private float _scale = 4f;
private Texture2D _pixel;
private Texture2D _spriteSheet;
private Point _spriteSize = new Point(16);
private Point _playerSpriteIndex = new Point(0, 10);
private int _frameOffset = 0;
private double _frameAccum = SPRITE_FRAMERATE_PLAYER;
private Vector2 _playerPos = new Vector2(100);
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
_graphics.PreferredBackBufferWidth = 1280;
_graphics.PreferredBackBufferHeight = 720;
_graphics.ApplyChanges();
base.Initialize();
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
_pixel = new Texture2D(_graphics.GraphicsDevice, 1, 1);
_pixel.SetData<Color>(new Color[] { Color.White });
_spriteSheet = this.Content.Load<Texture2D>("Sprites");
}
protected override void Update(GameTime gameTime)
{
_frameAccum -= gameTime.ElapsedGameTime.TotalSeconds;
if (_frameAccum <= 0)
{
_frameOffset = 1 - _frameOffset;
Console.WriteLine(_frameOffset);
_frameAccum += SPRITE_FRAMERATE_PLAYER;
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
_spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp);
_spriteBatch.Draw(
_spriteSheet,
_playerPos,
new Rectangle((_playerSpriteIndex + new Point(_frameOffset, 0)) * _spriteSize , _spriteSize),
Color.White,
0f,
Vector2.Zero,
4f,
SpriteEffects.None,
0f
);
_spriteBatch.Draw(
_spriteSheet,
_playerPos + new Vector2(32 * _scale, 0),
new Rectangle((_playerSpriteIndex + new Point(_frameOffset, 0)) * _spriteSize - new Point(0, 1) , _spriteSize),
Color.White,
0f,
Vector2.Zero,
_scale,
SpriteEffects.None,
0f
);
_spriteBatch.End();
base.Draw(gameTime);
}
}
So I’m rendering the sprite twice. Once at where it should be, and again at one pixel up from where it should be (at 4x the size to make it easier to see).
The one on the right looks a lot like yours. I also checked the pixel size in the sprites you’re rendering and they are 16 high, so it’s not like you have them sized wrong somehow.
You want to calculate your rectangle as…
Rectangle sourceRectangle = new Rectangle(
spriteIndex * spriteSize,
spriteSize
);
spriteIndex is the column/row the sprite is at, 0 based. So for the sprite I’m showing, it’s starting at (0, 10), animating to (1, 10), and then back.