Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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
        {
            --cameraDirection.X;
        }
        if (playerScreenRect.Right > GraphicsDevice.Viewport.Width - TO_MOVE_SIDE_DISTANCE) // move to the right
        {
            ++cameraDirection.X;
        }
        if (playerScreenRect.Top < TO_MOVE_SIDE_DISTANCE) // move up
        {
            --cameraDirection.Y;
        }
        if (playerScreenRect.Bottom > GraphicsDevice.Viewport.Height - TO_MOVE_SIDE_DISTANCE) // move down
        {
            ++cameraDirection.Y;
        }

        cam.Pos += cameraDirection * player._PlayerSpeed; // move with the player.

The Solution is here.

share|improve this question
1  
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
2  
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

2 Answers 2

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.

share|improve this answer
    
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.

share|improve this answer
    
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 ;-) –  eBusiness Jun 2 '11 at 18:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.