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