Viewport / Camera Calculation in 2D Game

Posted by Dave on Game Development See other posts from Game Development or by Dave
Published on 2012-06-15T09:45:37Z Indexed on 2012/06/15 15:28 UTC
Read the original article Hit count: 283

Filed under:
|

we have a 2D game with some sprites and tiles and some kind of camera/viewport, that "moves" around the scene. so far so good, if we wouldn't had some special behaviour for your camera/viewport translation.

normally you could stick the camera to your player figure and center it, resulting in a very cheap, undergraduate, translation equation, like :

vec_translation -/+= speed (depending in what keys are pressed. WASD as default.)

buuuuuuuuuut, we want our player figure be able to actually reach the bounds, when the viewport/camera has reached a maximum translation.


we came up with the following solution (only keys a and d are the shown here, the rest is just adaption of calculation or maybe YOUR super-cool and elegant solution :) ):

if(keys[A])
{
    playerX -= speed;

    if(playerScreenX <= width / 2 && tx < 0)
    {
        playerScreenX = width / 2;
        tx += speed;
    }
    else if(playerScreenX <= width / 2 && (tx) >= 0)
    {
        playerScreenX -= speed;
        tx = 0;

        if(playerScreenX < 0) playerScreenX = 0;
    }
    else if(playerScreenX >= width / 2 && (tx) < 0)
    {
        playerScreenX -= speed;
    }
}
if(keys[D])
{
    playerX += speed;

    if(playerScreenX >= width / 2 && (-tx + width) < sceneWidth)
    {
        playerScreenX = width / 2;
        tx -= speed;
    }
    if(playerScreenX >= width / 2 && (-tx + width) >= sceneWidth)
    {
        playerScreenX += speed;
        tx = -(sceneWidth - width);
        if(playerScreenX >= width - player.width) playerScreenX = width - player.width;
    }
    if(playerScreenX <= width / 2 && (-tx + width) < sceneWidth)
    {
        playerScreenX += speed; 
    }
}

i think the code is rather self explaining:

keys is a flag container for currently active keys, playerX/-Y is the position of the player according to world origin, tx/ty are the translation components vital to background / npc / item offset calculation, playerOnScreenX/-Y is the actual position of the player figure (sprite) on screen and width/height are the dimensions of the camera/viewport.

this all looks quite nice and works well, but there is a very small and nasty calculation error, which in turn sums up to some visible effect.

let's consider following piece of code:

if(playerScreenX <= width / 2 && tx < 0)
{
    playerScreenX = width / 2;
    tx += speed;
}

it can be translated into plain english as : if the x position of your player figure on screen is less or equal the half of your display / camera / viewport size AND there is enough space left LEFT of your viewport/camera then set players x position on screen to width half, increase translation (because we subtract the translation from something we want to move). easy, right?! doing this will create a small delta between playerX and playerScreenX.

after so much talking, my question appears now here at the bottom of this document:

how do I stick the calculation of my player-on-screen to the actual position of the player AND having a viewport that is not always centered aroung the players figure?

here is a small test-case in processing:

http://pastebin.com/bFaTauaa

thank you for reading until now and thank you in advance for probably answering my question.

© Game Development or respective owner

Related posts about 2d

Related posts about camera