0
\$\begingroup\$

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.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Ikke
    Commented May 27, 2011 at 9:04
  • 2
    \$\begingroup\$ To format larger code blocks, indent 4 spaces instead of using `` \$\endgroup\$
    – Ikke
    Commented May 27, 2011 at 9:59
  • \$\begingroup\$ How do you calculate squaresDown and squaresAcross? Did you try increasing these values by 1? \$\endgroup\$
    – bummzack
    Commented May 30, 2011 at 11:52

2 Answers 2

2
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ sounds good, but increasing the draw makes the game lag thats why i chose not to. \$\endgroup\$
    – Bert
    Commented May 31, 2011 at 8:24
  • \$\begingroup\$ 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. \$\endgroup\$ Commented May 31, 2011 at 12:34
  • \$\begingroup\$ 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 \$\endgroup\$ Commented May 31, 2011 at 14:50
2
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ 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 \$\endgroup\$
    – Bert
    Commented Jun 2, 2011 at 15:51
  • \$\begingroup\$ Every good programmer reached that status through bad code ;-) \$\endgroup\$ Commented Jun 2, 2011 at 18:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .