# How do i get my tilemap to move at the same speed as my character

I have a little problem in my solution, i'm trying to make a pretty big map for the players to walk around in.

I decided to use a tile-engine, but when I move my character it moves faster than my tile-engine draws the ground so I end up catching up to the edge. It's quite hard to explain so I've added the solution at the end. Just keep walking down or right and you'll see the problem: while the world keeps generating slowly my character moves faster. Sounds like it's just a matter of changing my characters movement speed, but that doesn't help at all.

This is the code for drawing the tiles

`````` Vector2 firstSquare = new Vector2(cam.Pos.X / Tile.TileWidth, cam.Pos.Y / Tile.TileHeight);

//Vector2 worldFirstSquare = cam.GetWorldPosition(firstSquare);
int firstX = (int)firstSquare.X;
int firstY = (int)firstSquare.Y;

Vector2 squareOffset = new Vector2(cam.Pos.X % Tile.TileWidth, cam.Pos.Y % Tile.TileHeight);
//Vector2 worldSquareOffset = cam.GetWorldPosition(squareOffset);
int offsetX = (int)squareOffset.X;
int offsetY = (int)squareOffset.Y;

if (Mouse.GetState().LeftButton == ButtonState.Pressed)
{
Console.WriteLine(firstSquare + " " + squareOffset);
}

for (int y = 0; y < squaresDown; y++)
{
for (int x = 0; x < squaresAcross; x++)
{
if(firstY >=0 && firstX >=0)
foreach (int tileID in myMap.Rows[y + firstY].Columns[x + firstX].BaseTiles)
{
spriteBatch.Draw(
Tile.TileSetTexture,
new Rectangle(
(x * Tile.TileWidth) - offsetX, (y * Tile.TileHeight) - offsetY,
Tile.TileWidth, Tile.TileHeight),
Tile.GetSourceRectangle(tileID),
Color.White);
}
}
}
``````

This is for moving my character

``````if (keystate.IsKeyDown(Keys.W))
{
if (keystate.IsKeyDown(Keys.A))
{
_PlayerRect.Y -= _PlayerSpeed -2;
_PlayerRect.X -= _PlayerSpeed -2;
}
else if (keystate.IsKeyDown(Keys.D))
{
_PlayerRect.Y -= _PlayerSpeed -2;
_PlayerRect.X += _PlayerSpeed -2;
}
else
{
_PlayerRect.Y -= _PlayerSpeed;
}
}
else if (keystate.IsKeyDown(Keys.S))
{
if (keystate.IsKeyDown(Keys.A))
{
_PlayerRect.Y += _PlayerSpeed -2;
_PlayerRect.X -= _PlayerSpeed -2;
}
else if(keystate.IsKeyDown(Keys.D))
{
_PlayerRect.Y += _PlayerSpeed -2;
_PlayerRect.X += _PlayerSpeed -2;
}
else
{
_PlayerRect.Y += _PlayerSpeed;
}
}
else if (keystate.IsKeyDown(Keys.A))
{
_PlayerRect.X -= _PlayerSpeed;
}
else if (keystate.IsKeyDown(Keys.D))
{
_PlayerRect.X += _PlayerSpeed;
}

playerPosition.X = _PlayerRect.X;
playerPosition.Y = _PlayerRect.Y;
``````

And this is the update for my camera

``````Vector2 cameraDirection = Vector2.Zero;
const int TO_MOVE_SIDE_DISTANCE = 300; // the distance to the side required to move.

Vector2 playerScreenPosition = cam.GetScreenPosition(new Vector2(
player.PlayerRect.X, player.PlayerRect.Y));
Rectangle playerScreenRect = new Rectangle((int)playerScreenPosition.X,
(int)playerScreenPosition.Y, player.PlayerRect.Width, player.PlayerRect.Height);

//We make the camera follow the player if he goes too close to the sides.

if (playerScreenRect.Left < TO_MOVE_SIDE_DISTANCE) // move to the left
{
}
if (playerScreenRect.Right > GraphicsDevice.Viewport.Width - TO_MOVE_SIDE_DISTANCE) // move to the right
{
}
if (playerScreenRect.Top < TO_MOVE_SIDE_DISTANCE) // move up
{
}
if (playerScreenRect.Bottom > GraphicsDevice.Viewport.Height - TO_MOVE_SIDE_DISTANCE) // move down
{
}

cam.Pos += cameraDirection * player._PlayerSpeed; // move with the player.
``````
-
Maybe you could add some relevant code to the question so people won't have to dive into your code to find out what happens. – Ikke May 27 '11 at 9:04
thanks for the tip, i did – Bert May 27 '11 at 9:13
To format larger code blocks, indent 4 spaces instead of using `` – Ikke May 27 '11 at 9:59
How do you calculate `squaresDown` and `squaresAcross`? Did you try increasing these values by 1? – bummzack May 30 '11 at 11:52

The easiest way to solve this issue is, to put it simply, draw more :-) it's usually ok if you draw stuff just outside of the viewport. That reduces instances where the visible area "catches up" with the edge of the screen before it redraws.

You can of course get more complex with it where you increase the drawing distance only in the direction that you're moving ... but usually this is overkill.

-
sounds good, but increasing the draw makes the game lag thats why i chose not to. – Bert May 31 '11 at 8:24
Don't forget that there is a fine balance between over-optimizing CPU side and drawing too much. If you offload too much work to clipping, etc on the CPU, it may harm your performances. – Jonathan Connell May 31 '11 at 12:34
You probably want to do some profiling here ... because there's a chance you could make big gains by improving an algorithm or two which would make room for the overdraw – Joel Martinez May 31 '11 at 14:50

Your code is really hard to read, and I can't get it to run, so I'm not sure what is actually going on.

But as far as I can tell you are both moving around the camera and changing the place where the tiles are drawn depending on player position, you should only do one of those.

Edit: I got it running, no performance problems, this is a simple case of camera/object position mismatch.

-
hmmm thanks, i think that just might be the problem :) and about the hard to read code, i'm not all that good yet :S sorry – Bert Jun 2 '11 at 15:51
Every good programmer reached that status through bad code ;-) – aaaaaaaaaaaa Jun 2 '11 at 18:04