0
\$\begingroup\$

I have a large map that a player will navigate over. Currently, it is just a single background image, but I would like to make it tiled map. How do I properly keep track of player coordinates?

Currently what I have working is:

1) I have a 800px wide by 500px high playing area 2) The player is normally positioned in the center of the screen at approximately (400px x 250px) 3) When the arrow keys are pressed instead of the player moving the map moves. I am currently using background-position at the moment to set which area of a background is displayed.

What I am currently trying to wrap my head around:

4) When the map reaches the boundaries it will no longer scroll, but my player is stuck in the center. 5) How to get the player back to the center again when they start to travel away from the corners.

The main problem I am having is knowing what coordinates I should be keeping track of. For example, should I be keeping track on only one of the following, or all three of the following:

  • Player position in map
  • Map position on screen
  • Player position on screen

What is a standard way to handle player movement like this?

\$\endgroup\$
0
\$\begingroup\$

The way this is typically handled is to introduce a notion of a "camera" to your game.

The camera is another entity that exists at some position in the game world, like your player character. It represents the current point of view, from which you can determine what should be visible and where to draw it on the screen.

With this approach, all your entity positions are stored/tracked/manipulated in your world's coordinate system, relative to a fixed point in your game world, so they're completely decoupled from the pixel grid of your screen. As a side benefit, this makes it much easier to adapt your game to different screen resolutions, or handle changes in your graphics assets later, since all your gameplay code is in world coordinates and can remain unchanged.

Each frame, you update the camera's position after the player has moved. For example, to follow the player when they're in the middle of the map, but stop at the world bounds, you can write something like this:

// Update the worldspace bounds of our camera view, in case the window changed size.
camera.worldHalfWidth = displayArea.pixelWidth / camera.pixelsPerWorldUnit;
camera.worldHalfHeight = displayArea.pixelHeight / camera.pixelsPerWorldUnit;

camera.x = Math.max(camera.worldHalfWidth, Math.min(player.x, world.width - camera.worldHalfWidth));
camera.y = Math.max(camera.worldHalfHeight, Math.min(player.x, world.height - camera.worldHalfHeight));

When it comes time to draw the background and entities in your game world, you can use the camera to decide where they belong:

worldToScreenPoint = function(worldPoint) {
    var worldOffset = new Point(worldPoint.x - camera.x, worldPoint.y - camera.y);
    var pixelOffset = new Point(worldOffset.x * camera.pixelsPerWorldUnit, worldOffset.y * camera.pixelsPerWorldUnit);
    return new Point(displayArea.center.x + pixelOffset.x, displayArea.center.y + pixelOffset.y);
}

(My apologies if my Javascript is a little crude - I mostly use C# these days. Hopefully it's enough to convey the important steps!)

If you're drawing on a canvas, you can equivalently use the 2D context's transformation methods to apply the world-to-pixel coordinate conversion, and use the camera as a way to update that transformation.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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