Javascript 仅在可见画布区域绘制平铺贴图-优化

Javascript 仅在可见画布区域绘制平铺贴图-优化,javascript,canvas,Javascript,Canvas,我刚刚想到了如何只画画布中的图像(javascript tilemap游戏)。然而,我不确定这是否像我认为的那样得到了充分的优化。关于如何使其更加优化,有什么想法吗 目前,我使用map数组对Y和X进行循环,然后对Y中的每个X使用带位置坐标的drawImage。在绘制之前,我放置了一个if语句来检查当前的X和Y是否在画布中。如果是,则绘制图像。下面是一段代码,可以说明这一点,稍后将给出一个链接来测试它 var mapArray=[ [3,3

我刚刚想到了如何只画画布中的图像(javascript tilemap游戏)。然而,我不确定这是否像我认为的那样得到了充分的优化。关于如何使其更加优化,有什么想法吗

目前,我使用map数组对Y和X进行循环,然后对Y中的每个X使用带位置坐标的drawImage。在绘制之前,我放置了一个if语句来检查当前的X和Y是否在画布中。如果是,则绘制图像。下面是一段代码,可以说明这一点,稍后将给出一个链接来测试它

            var mapArray=[

                [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3],
                [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
                [3,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,3],
                [3,0,1,1,1,1,0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,3],
                [3,0,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,1,0,0,0,3],
                [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
                [3,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,3],
                [3,0,1,1,1,1,0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,3],
                [3,0,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,1,0,0,0,3],
                [3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
                [3,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,3],
                [3,0,1,1,1,1,0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,3],
                [3,0,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,1,0,0,0,3],
                [3,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,3],
                [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]
            ];

// x= 22
// y= 15




//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
                  // DRAW PLAYER

var player = new Object();
player.y = canvas.height/2-40;    //player position - middle of canvas - 40
player.x = canvas.width/2-40;     //player position - middle of canvas - 40
player.Width = 80;
player.Height = 80;
  player_image = new Image();
  player_image.src = 'http://sarahkerrigan.biz/wpmtest/1/images/horseright1.png';




function drawPlayer() {      // drawing the player
    context.beginPath();
    context.drawImage(player_image, player.x, player.y, player.Width, player.Height);
    context.closePath();
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------



      var updateX=(player.x-210);  // Starting point of canvas X
      var updateY=(player.y-160);  // Starting point of canvas Y
            var posX=updateX;
            var posY=updateY;




//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
       //DRAW THE MAP AND THE PLAYER      

function drawMap() {

var posY = updateY;    // new Y coordinates for the map after movement


var grass = new Image();
var stone = new Image();
var black = new Image();
            grass.src= 'http://sarahkerrigan.biz/wpmtest/1/images/tile/grass.jpeg';
            stone.src = 'http://sarahkerrigan.biz/wpmtest/1/images/tile/sand.jpeg';
            black.src = 'http://sarahkerrigan.biz/wpmtest/1/images/tile/black.png';

   //---------------------------------------------------------
                    // Draw the map loop
            grass.onload = function (){
            stone.onload = function (){
            black.onload = function (){
            for(var i=0; i < mapArray.length; i++){
                for(var j=0; j < mapArray[i].length; j++){


   //=======================================================================   
            //CHECK IF X AND Y POSITIONS OF THE TILE ARE WITHIN THE CANVAS
   //=======================================================================
                    if(mapArray[i][j]==0){
               if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX){
                        context.drawImage(grass,posX, posY, 64, 64);   // Load image for grass "0"
                           }
                    }



                    if(mapArray[i][j]==1){
               if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX){
                        context.drawImage(stone,posX,posY,64,64);     // Load image for stone "1"
                           }
                    }



                    if(mapArray[i][j]==3){
               if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX){
                        context.drawImage(black,posX,posY,64,64);     // Load image for black "3"
                           }
                    }
     //=======================================================================

                    posX+=64;
                }
                posY+=64;
                posX=updateX;   // new X coordinates for the map after movement
   //---------------------------------------------------------
              drawPlayer();          // Draw the player
            }
        }
     }
    }
}


//-----------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
var映射数组=[
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3],
[3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
[3,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,3],
[3,0,1,1,1,1,0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,3],
[3,0,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,1,0,0,0,3],
[3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
[3,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,3],
[3,0,1,1,1,1,0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,3],
[3,0,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,1,0,0,0,3],
[3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
[3,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,3],
[3,0,1,1,1,1,0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,3],
[3,0,1,0,0,1,1,1,0,0,0,0,1,0,0,1,1,1,0,0,0,3],
[3,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,3],
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]
];
//x=22
//y=15
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
//平局球员
var player=新对象();
player.y=canvas.height/2-40//球员位置-画布中间-40
player.x=canvas.width/2-40//球员位置-画布中间-40
播放器宽度=80;
运动员身高=80;
player_image=新图像();
player_image.src=http://sarahkerrigan.biz/wpmtest/1/images/horseright1.png';
函数drawPlayer(){//绘制播放器
context.beginPath();
context.drawImage(player_image,player.x,player.y,player.Width,player.Height);
closePath();
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
var updateX=(player.x-210);//画布X的起点
var updateY=(player.y-160);//画布Y的起点
var posX=updateX;
var posY=updateY;
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//画地图和玩家
函数drawMap(){
var posY=updateY;//移动后地图的新Y坐标
var grass=新图像();
var stone=新图像();
var black=新图像();
grass.src=http://sarahkerrigan.biz/wpmtest/1/images/tile/grass.jpeg';
stone.src=http://sarahkerrigan.biz/wpmtest/1/images/tile/sand.jpeg';
black.src=http://sarahkerrigan.biz/wpmtest/1/images/tile/black.png';
//---------------------------------------------------------
//绘制地图循环
grass.onload=函数(){
stone.onload=函数(){
black.onload=函数(){
对于(var i=0;icanvasBegY&&posYcanvasBegX&&posXcanvasBegY&&posYcanvasBegX&&posXcanvasBegY&&posYcanvasBegX&&posX
它看起来很简单,这就是为什么我想检查一下,是否有任何东西可以让它更优化

这里有一个链接
setInterval(gameLoop, 30);        // 30 milisec to draw next frame
function gameLoop(){
   playerMovement();          //Check for movements
   drawMap();                 //Draw the map and the player

   /* NEVER use setInterval or setTimeout for animating anything!!! */
   //setInterval(gameLoop, 30);        // 30 milisec to draw next frame

   // use this. It will automatically slow down the frame rate to 30frames 
   // 20, 15, 10 and so on, per second if your render code is slow.
   requestAnimationFrame(gameLoop);
}
function drawMap() {

    var posY = updateY; // new Y coordinates for the map after movement


    var grass = new Image();
    var stone = new Image();
    var black = new Image();
    grass.src = 'http://sarahkerrigan.biz/wpmtest/1/images/tile/grass.jpeg';
    stone.src = 'http://sarahkerrigan.biz/wpmtest/1/images/tile/sand.jpeg';
    black.src = 'http://sarahkerrigan.biz/wpmtest/1/images/tile/black.png';

    grass.onload = function () {
        stone.onload = function () {
            black.onload = function () {
                for (var i = 0; i < mapArray.length; i++) {
                    for (var j = 0; j < mapArray[i].length; j++) {

                        if (mapArray[i][j] == 0) {
                            if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX) {
                                context.drawImage(grass, posX, posY, 64, 64); // Load image for grass "0"
                            }
                        }

                        if (mapArray[i][j] == 1) {
                            if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX) {
                                context.drawImage(stone, posX, posY, 64, 64); // Load image for stone "1"
                            }
                        }

                        if (mapArray[i][j] == 3) {
                            if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX) {
                                context.drawImage(black, posX, posY, 64, 64); // Load image for black "3"
                            }
                        }

                        posX += 64;
                    }
                    posY += 64;
                    posX = updateX; // new X coordinates for the map after movement
                    drawPlayer(); // Draw the player
                }
            }
        }
    }
}
const imageSrcDir = "http://sarahkerrigan.biz/wpmtest/1/images/tile/"
const tileImages = [];
function loadImages(images) {
    images.forEach(image => {
        const img = tileImages[image.mapIndex] = new Image();
        img.src = imageSrcDir + image.name;
    });
}
// load the images and add to the tileImage array
loadImages([
    { name : "grass.jpeg", mapIndex : 0 },
    { name : "stone.jpeg", mapIndex : 1 },
    { name : "black.png", mapIndex : 3 },
]);
const testMap = [
    "3333333333333333333333",
    "3000000000000000000003",
    "3000111000000011100003",
    "3011110000101111000013",
    "3010011100001001110003",
    "3000000000000000000003",
    "3000111000000011100003",
    "3011110000101111000013",
    "3010011100001001110003",
    "3000000000000000000003",
    "3000111000000011100003",
    "3011110000101111000013",
    "3010011100001001110003",
    "3000011000000001100003",
    "3333333333333333333333",
];
function createMap(map){
    const newMap = {};
    newMap.width = map[0].length;
    newMap.height = map.length;
    newMap.array = new Uint8Array(newMap.width * newMap.height);
    var index = 0;
    for(const row of map){
         var i = 0;
         while(i < row.length){
             newMap.array[index++] = Number(row[i++]);
         }
    }
    return newMap;
}
const currentMap = createMap(testMap);       
const tileWidth = 64;
const tileHeight = 64;
var playerX = 6; // in tile coordinates 6.5 would be halfway to till 7
var playerY = 2;

var mapX = 0;  // the map position so that the player can be seen
var mapY = 0;


// get the map position
function getMapPosition(){
    // convert player to pixel pos
    var x = playerX * tileWidth;
    var y = playerY * tileHeight; 
    x -= canvas.width / 2;     // center on the canvas
    y -= canvas.heigth / 2;       
    mapX = x;
    mapY = y;
}
function drawMap(map) {
    const w = map.width; // get the width of the tile array
    const mArray = map.array;
    const tx = mapX / tileWidth | 0; // get the top left tile
    const ty = mapY / tileHeight | 0;
    const tW = (canvas.width / tileWidth | 0) + 2; // get the number of tiles to fit canvas
    const tH = (canvas.height / tileHeight | 0) + 2;
    // set the location via the transform
    // From here on you draw all the game items relative to the map not the canvas
    ctx.setTransform(1, 0, 0, 1, -mapX | 0, -mapY | 0);

    // Draw the tiles if tile pos is off map draw black tile
    for (var y = 0; y < tH; y += 1) {
        for (var x = 0; x < tW; x += 1) {
            const i = tx + x + (ty + y) * w;
            const tileIndex = mArray[i] === undefined ? 3 : mArray[i]; // if outside map draw black tile
            ctx.drawImage(tileImages[tileIndex], (tx + x) * tileWidth, (ty + y) * tileHeight);
        }
    }

}