-1
\$\begingroup\$

I am developing a canvas game, and im struggling to get my head around how i can make a view port so when the character moves the world moves with it.

Unlike traditional 2d maps built with arrays i have loaded in a json file from tiled map editor and here is the code where the images get drawn to the canvas:

this.draw_layer = function(layer){

    var size = data.tilewidth;
    layer.data.forEach(function(tile_idx, i) {
        if (!tile_idx) { return; }
        var img_x, img_y, s_x, s_y,
            tile = data.tilesets[0];
        tile_idx--;
        img_x = (tile_idx % (tile.imagewidth / size)) * size;
        img_y = ~~(tile_idx / (tile.imagewidth / size)) * size ;
        s_x = (i % layer.width) * size;
        s_y = ~~(i / layer.width) * size;
        ctx.drawImage(Level.tileset, img_x, img_y, size, size,
            s_x, s_y, size, size);
    });
}; 

Here is the update function for my character:

this.update = function(elapsed) {
    var prev_X = x;
    var prev_Y = y;
    collided = false;

    switch (this.keys[this.keys.length - 1])
    {
        case 37:
            // move the player left on the screen
            x -= this.moveSpeed * elapsed;
            break;
        case 38:
            // move the player up on the screen
            y -= this.moveSpeed * elapsed;
            break;
        case 39:
            // move the player right on the screen
            x += this.moveSpeed * elapsed;
            break;
        case 40:
            // move the player down on the screen
            y += this.moveSpeed * elapsed;
            break;
    }

    if (x < 0)
    {
        x = 0;
    }
    if (x >= gameW - w)
    {
        x = gameW - w;
    }
    if (y < 0)
    {
        y = 0;
    }
    if (y >= gameH - h)
    {
        y = gameH - h;
    }

    for (var i = 0;i<collision_array.length; i++)
    {

        var block_x = collision_array[i][0],
            block_y = collision_array[i][1],
            block_w = collision_array[i][2],
            block_h = collision_array[i][3];


            if ((x < (block_x + block_w) && Math.floor(x + w) > block_x)
                && (y < (block_y + block_h) && Math.floor(y + h) > block_y))
            {
                if(collision_array[i][4] == "dialogue"){
                    dialog.say(collision_array[i][5])
                }
                else if(collision_array[i][4] == "object"){
                    dialog.set_inv(collision_array[i][6]);
                }
                else{
                    $('#dialog').hide();
                    x = prev_X;
                    y = prev_Y;
                }
            }
    }
    return {
        'pos_X':x,
        'pos_Y':y
    };
};

SO my question is, for the way i am loading my maps, how would i create a view port to move the map whilst the player is moving?

Also what do i do with the character when the view port reaches an edge of the view port? How would i let him move to the edge too?

Thanks for you time

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Have a look at canvas.translate. To scroll your view of the map, use translate to move the origin of coordinate system relative to the canvas element on your page.

To put it another way: Instead of scrolling the "viewport" around the map, the viewport remains stationary and you just move the entire canvas.

Then the trick is, getting the character's position and calculating the required translation. You'll (probably) need to stop scrolling when you hit the side of a level, for example, to avoid viewing graphics space which is "out of bounds".

For reference, many graphics interfaces in many libs and languages have some sort of translate function, but they behave differently. For example, the java.awt.Graphics.translate is absolute; each time you call it, the translation occurs in relation to the default origin of (0, 0). So if you call graphics.translate(10, 20), the graphics origin will be moved/scrolled 10 pixels on the x-axis and 20 on the y-axis. Calling this function again with the same args will not do anything; the new origin will remain at (10, 20).

By contrast, canvas.translate is relative, meaning that each time you call it the translation occurs in relation to the current origin. If you call canvas.translate(10, 20), the origin will be moved to (10, 20). If you call canvas.translate(10, 20) again, the origin will be moved to (20, 40).

\$\endgroup\$

You must log in to answer this question.

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