The sprite has both a tile where it is located and an offset in pixels from the corner of that tile. To move the sprite, you increment the pixel offset smoothly and check for when it exits the bounds of the tile, and move it to the next tile. (Of course, the sprite also has an origin with respect to it's position, which I didn't implement here since that's orthogonal to this problem. I also didn't do any bounds checking, since the game should do that, not the sprite)
Code:
class Sprite
{
Sprite( int initialX, int initialY )
: mOffsetX( initialX ), mOffsetY( initialY )
{
mTileX = mOffsetX / TILE_WIDTH;
mOffsetX = mOffsetX % TILE_WIDTH;
mTileY = mOffsetY / TILE_HEIGHT;
mOffsetY = mOffsetY % TILE_HEIGHT;
}
void Move( int moveX, int moveY )
{
BumpCoordinate( mOffsetX, mTileX, TILE_WIDTH, moveX );
BumpCoordinate( mOffsetY, mTileY, TILE_HEIGHT, moveY );
}
// Get the coordinate of the current tile (measured in tiles)
int GetTileX() const { return mTileX; }
int GetTileY() const { return mTileY; }
// Get the absolute position in pixels
int GetX() const { return mTileX * TILE_WIDTH + mOffsetX; }
int GetY() conset { return mTileY * TILE_HEIGHT + mOffsetY; }
private:
int mTileX;
int mTileY;
int mOffsetX;
int mOffsetY;
void BumpCoordinate( int &coord, int &tile, int size, int bump )
{
coord += bump;
// Avoid division and modulus for the common case where we don't move
// farther than a single tile at once.
while( coord >= size ) { coord -= size; ++tile; }
while( coord < 0 ) { coord += size; --tile; }
}
};