[Tutorial]Building a Simple TileMap Game, Part 3 of 9

Rendering the Viewport and Player


From the player’s coordinates, we can calculate the coordinates of the view port. Typically, the player will be rendered in the centre of the screen and the viewport will show the world relative to the player’s position in the world.

A function for calculating the view port’s coordinates is shown below. The calculation for the X and Y values are similar and divided into three tests – is the player within one half the width of the view port of the left-hand side of the world in which case the viewport should be rendered alongside the world’s left-hand side (x = 0).

If not, is the player within one half the width of the view port of the right-hand side of the world? If so, then the viewport should be rendered alongside the right-hand side of the world (x = worldWidth – PD::width). By the way, PD::width and PD::height are constants defined in the Pokitto library and represent the current display modes’ width and height. The sample code in this article run using Mode 2 and Mode 15 which have a width and height of 110 x 88 and 220 x 176 respectively.

If neither of these are true, the viewport should be rendered relative to the player (x = player’s X position – PD::width / 2).


void calculateViewPortPosition(int16_t &xViewPort, int16_t &yViewPort) {
    
    // Calculate the x position ..

    if (x < PD::width / 2) {
        
        xViewPort = 0;
        
    }
    else if (x > worldWidth - PD::width / 2) {

        xViewPort = worldWidth - PD::width;
        
    }
    else {
        
        xViewPort = x - PD::width / 2;

    }
    
    …
    
}

Using this function, we can calculate the viewport’s offset and use this when calling the Tilemap classes draw() function.

    int16_t xViewPort;
    int16_t yViewPort;
        
    calculateViewPortPosition(xViewPort, yViewPort);
    tilemap.draw(xViewPort, yViewPort);

So far the scenarios shown have not included the case where a player is moving to an edge of the world. In the image below, the player has moved to the right and the viewport is now hard up against the right-hand side of the world. If the player was to move further right, we cannot move the viewport any more so to compensate, we render the player right of the viewport’s centre line.

image

Download and review the code in the repo https://github.com/filmote/Tilemap_1 It contains a function, similar to the calculateViewportPosition() above, which determines the coordinates at which to render the player. The calculation for the X and Y values are similar and divided into three tests – is the player within one half the width of the view port of the left-hand side of the world in which case the player should be rendered alongside the world’s left-hand side (x = player’s x position).

If not, is the player within one half the width of the view port of the right-hand side of the world? If so, then the player should be rendered at the current x position less the difference in size between the worlds and viewport’s width (x = player’s x position – (worldWidth – PD::Width)).

If neither of these are true, the player should be rendered in the centre of the screen (x = PD::width / 2).


void calculatePlayerPosition(int16_t &xPlayer, int16_t &yPlayer) {
    
    if (x < PD::width / 2) {
        
        xPlayer = x;
        
    }
    else if (x > worldWidth - PD::width / 2) {

        xPlayer = x - (worldWidth - PD::width);
        
    }
    else {
        
        xPlayer = PD::width / 2;

    }
    
    …

}

Review the omitted code from the calculateViewportPosition() and calculatePlayerPosition() functions. The two functions are similar in structure and the calculation of the Y coordinate in both is nearly identical to the calculation of the X coordinate.




<< Prev | Next >>

Part 1 of 9: Building a Simple Tilemap Game
Part 2 of 9: Moving a Player Around the World
Part 3 of 9: Rendering the Viewport and Player
Part 4 of 9: Detecting Obstacles
Part 5 of 9: Adding Enemies
Part 6 of 9: Using FemtoIDE and Piskel
Part 7 of 9: Doors and Inventory Items
Part 8 of 9: Multiple Worlds
Part 9 of 9: Sixteen Tiles Only?

2 Likes