gpt4 book ai didi

javascript - HTML5 Canvas 游戏,多层问题

转载 作者:可可西里 更新时间:2023-11-01 14:46:04 26 4
gpt4 key购买 nike

我正在创建我的第一个 HTML5 游戏。这是一款类似于 Ministry of War/War of Legends 的游戏。这是一款基于等距图 block 的 MMORTS 游戏。现在,当我构建游戏时,我试图牢记资源管理和速度;但是,我遇到了一个问题。

我有一个名为 renderMap 的方法遵循这些步骤

  1. renderMap 加载当前 map block 。 map block 目前被定义为 6x6 的图 block 网格。
  2. renderMap 从 ASCENDING X,Y 到 DESCENDING X,Y 遍历每个单独的图 block ,并将该图 block 绘制到等距网格上。在将图 block 绘制到屏幕上时,它还会检查该图 block 上是否有建筑物,并将该建筑物绘制在图 block 之上。

现在,因为 renderMap 必须为 block 中的每个单独的图 block 调用 drawImage 大约 36 次,如果函数被调用每一帧。因此,我将 renderMap 绘制到内存中的 Canvas 上,每帧都会将其绘制到主 Canvas 上。因此,每帧 36 次调用 drawImage 的次数减少到只有 1 次。

而且我唯一需要调用 renderMap 的时间是瓷砖或建筑物无论如何都会更新。例如,如果加载了一个新 block ,我们需要加载新的等轴测图。

但是,如果我想让这些建筑物或瓷砖有动画怎么办?

例如,我在游戏中添加了一座名为油井的建筑。如果油井位于玩家客户端加载并显示的 6x6 block 中的任何一个图 block 上,这将迫使游戏不得不多次调用 renderMap,以便渲染那栋建筑的新形象(因为动画)。所以我最终渲染了 35 个额外的图 block ,只是为了更新那 1 座建筑物。

我该怎么办?最好包含动画吗?

这是游戏的样子,所以这可能有助于为问题添加上下文:

(抱歉图片有点乱……我在做一点测试)

image of game

最佳答案

创建一个 spritesheet,其中包含为“油井”图 block 设置动画所需的所有图像。

然后您可以从该 spritesheet 中拉出 sprite,并将您渲染的 map 覆盖在该油井图 block 上。

然后您将渲染大 map 一次。您正在多次渲染那个图 block (比重新渲染整个 map 只是为了动画一个图 block 更有效的任务)。您可以使用第二个覆盖 Canvas 以获得最佳性能。您甚至可以制作一个只有单个 Sprite 大小的覆盖 Canvas ,然后使用 CSS 定位将其移动到目标图 block 上。

示例代码和演示:

var canvasT=document.getElementById("canvasTop");
var ctx=canvasT.getContext("2d");
var canvasB=document.getElementById("canvasBottom");
var ctxB=canvasB.getContext("2d");
var cw,ch;

var nextTime=0;
var duration=1000/60*3;
//
var spritesheetWidth=256;
var spritesheetHeight=256;
var spriteCols=4;
var spriteRows=4;
var spriteCount=spriteRows*spriteCols;
var spritePosition=0;
var spriteWidth=spritesheetWidth/spriteCols;
var spriteHeight=spritesheetHeight/spriteRows;
var fireX=265;
var fireY=100;
//
var imgCount=2;
var fire=new Image();
fire.onload=start;
fire.src='https://dl.dropboxusercontent.com/u/139992952/stackoverflow/explodeSprite.png'
var map=new Image();
map.onload=start;
map.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/isometric1.png";
function start(){
if(--imgCount>0){return;}
cw=canvasB.width=canvasT.width=map.width;
ch=canvasB.height=canvasT.height=map.height;
canvasB.width=map.width;
canvasB.height=map.height;
ctxB.drawImage(map,0,0);

animate();
}


function animate(time) {
if(time<nextTime){requestAnimationFrame(animate);return;}

nextTime=time+duration;

var row=parseInt(spritePosition/spriteCols);
var col=spritePosition-row*spriteCols;
var spX=col*spriteWidth;
var spY=row*spriteHeight;

// Drawing code goes here
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(fire,
spX,spY,spriteWidth,spriteHeight,
fireX,fireY,spriteWidth,spriteHeight);

spritePosition++;
if(spritePosition>spriteCount-1){
spritePosition=0;
}

requestAnimationFrame(animate);
}
body{ background-color: ivory; }
#wrapper{
position:relative;
width:1095px;
height:655px;

}
#canvasTop,#canvasBottom{
position:absolute; top:0px; left:0px;
border:1px solid green;
width:100%;
height:100%;
}
#canvasTop{
border:1px solid red;
}
<div id="wrapper">
<canvas id="canvasBottom"></canvas>
<canvas id="canvasTop"></canvas>
</div>

关于javascript - HTML5 Canvas 游戏,多层问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30408757/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com