最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - HTML5 - Creating a viewport for canvas - Stack Overflow

programmeradmin3浏览0评论

I have a 2D array that is 30 across, 20 down. However, the viewport only paints 15 across and 10 down. I had a game like that originally and I've been trying to achieve something like this:

Here's my fiddle: /

I have a 2D array that is 30 across, 20 down. However, the viewport only paints 15 across and 10 down. I had a game like that originally and I've been trying to achieve something like this:

Here's my fiddle: http://jsfiddle/sTr7q/

Share Improve this question asked Jul 13, 2012 at 5:20 testtest 18.2k67 gold badges173 silver badges245 bronze badges 3
  • Found this to be promising.. Not sure how I'd use it. kaioa./node/103 – test Commented Jul 13, 2012 at 5:23
  • Why doesn't your canvas have width and height attributes? Those define the workable area, while the css does not. – Daedalus Commented Jul 13, 2012 at 6:17
  • 1 Does this answer your question? HTML5 Canvas camera/viewport - how to actually do it? – ggorlen Commented Dec 26, 2020 at 18:40
Add a ment  | 

1 Answer 1

Reset to default 9

Here I've made a rudimentary viewport for you:

http://jsfiddle/kmHZt/

You have to keep track of the viewport X and Y (vX, vY) that represent where you are in the world at large. I also kept the viewport width and height as vars instead of hard coding them in.

You can use the arrow keys to change the viewport X and Y which will scroll the map, drawing only the correct tiles.

Hope that helps! Let me know if you have any questions!

EDIT: example of viewport moving with player: http://jsfiddle/kmHZt/10/

var canvas, context, board, imageObj, tiles, board, display;
var NUM_OF_TILES = 2;

// viewport
var vX = 0,
    vY = 0,
    vWidth = 15,
    vHeight = 10;

var playerX = 0,
    playerY = 0;

var worldWidth = 29,
    worldHeight = 19;

function loadMap(map) {
    if (map == 1) {
        return [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0], [0, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0], [0, 1, 1, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 0], [0, 1, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0], [0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 0], [0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];
    }
}

$(document).ready(function() {


    canvas = document.getElementById("canvas");
    context = canvas.getContext("2d");

    canvas.tabIndex = 0;
    canvas.focus();
    canvas.addEventListener('keydown', function(e) {
        console.log(e);
        var key = null;
        switch (e.which) {
        case 37:
            // Left
            if (playerX > 0) playerX--;
            break;
        case 38:
            // Up
            if (playerY > 0) playerY--;
            break;
        case 39:
            // Right
            if (playerX < worldWidth) playerX++;
            break;
        case 40:
            // Down
            if (playerY < worldHeight) playerY++;
            break;
        }
        // Okay! The player is done moving, now we have to determine the "best" viewport.
        // Ideally the viewport centers the player,
        // but if its too close to an edge we'll have to deal with that edge

        vX = playerX - Math.floor(0.5 * vWidth);
        if (vX < 0) vX = 0;
        if (vX+vWidth > worldWidth) vX = worldWidth - vWidth;


        vY = playerY - Math.floor(0.5 * vHeight);
        if (vY < 0) vY = 0;
        if (vY+vHeight > worldHeight) vY = worldHeight - vHeight;


        draw();
    }, false);

    var board = [];

    canvas.width = 512;
    canvas.height = 352;

    board = loadMap(1);
    imageObj = new Image();
    tiles = [];

    var loadedImagesCount = 0;
    for (x = 0; x <= NUM_OF_TILES; x++) {
        var imageObj = new Image(); // new instance for each image
        imageObj.src = "http://mystikrpg./canvas/img/tiles/t" + x + ".png";

        imageObj.onload = function() {
            // console.log("Added tile ... "+loadedImagesCount);
            loadedImagesCount++;
            if (loadedImagesCount == NUM_OF_TILES) {
                // Onces all tiles are loaded ...
                // We paint the map
                draw();
            }
        };
        tiles.push(imageObj);
    }


    function draw() {
        context.clearRect(0,0,canvas.width, canvas.height);
        for (y = 0; y <= vHeight; y++) {
            for (x = 0; x <= vWidth; x++) {
                theX = x * 32;
                theY = y * 32;
                context.drawImage(tiles[board[y+vY][x+vX]], theX, theY, 32, 32);
            }
        }
        context.fillStyle = 'red';
        context.fillRect((playerX-vX)*32, (playerY-vY)*32, 32, 32);
    }
});
发布评论

评论列表(0)

  1. 暂无评论