我正在制作一个JavaScript游戏引擎 - demo - 而且我想知道哪些选项在画布上绘制最便宜:
第一个选项需要比较每个对象和每个动画循环的四个或更多变量。我想知道这是否比绘制所有对象更便宜。
实际游戏中会有许多具有x和y坐标的物体,画布以较大的游戏地图为中心围绕人类玩家。
我使用requestAnimationFrame来进行绘制循环。我也没有使用任何框架。
答案 0 :(得分:0)
GPU会忽略屏幕外的绘图,因此渲染时间更短(嗯 - 不渲染!)。但是,CPU仍然会处理绘图命令,因此屏幕外的图形不会自由"。
但是你的第二次表现很受欢迎。您正在绘制自己路径中的每个圆圈:
ctx.beginPath();
ctx.arc(p.x,p.y,p.r,0,PI2);
ctx.fillStyle=p.color;
ctx.fill();
在单个(多圈)路径中绘制所有常见颜色的弧线效率更高:
ctx.fillStyle='red';
ctx.beginPath();
for(var i=0;i<len;i++){
var p=players[i];
if(p.color=='red'){
ctx.moveTo(p.x,p.y);
ctx.arc(p.x,p.y,p.r,0,PI2);
}
}
ctx.fill();
这是一组高度非优化的性能测试,显示:
beginPath
路径绘制屏幕上的圈子。beginPath
路径绘制离屏圈。在我适度的开发计算机上,这些是性能结果:
离屏/个别路径:427毫秒
屏幕/每种颜色一条路径:528毫秒
高度非优化的性能测试:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var colors=['red','green','blue','gold'];
var playersOnscreen=[];
var playersOffscreen=[];
for(var c=0;c<colors.length;c++){
var color=colors[c];
for(var p=0;p<100;p++){
playersOnscreen.push({x:50,y:50,r:10,color:color});
}
}
for(var c=0;c<colors.length;c++){
var color=colors[c];
for(var p=0;p<100;p++){
playersOffscreen.push({x:-50,y:50,r:10,color:color});
}
}
var count=100;
var t1=performance.now();
for(var i=0;i<count;i++){ drawIndividualPaths(playersOnscreen); }
var t2=performance.now();
for(var i=0;i<count;i++){ drawIndividualPaths(playersOffscreen); }
var t3=performance.now();
for(var i=0;i<count;i++){ drawColorPaths(playersOnscreen); }
var t4=performance.now();
for(var i=0;i<count;i++){ drawColorPaths(playersOffscreen); }
var t5=performance.now();
alert('onscreen/individual='+parseInt(t2-t1)+', offscreen/individual='+parseInt(t3-t2)+', onscreen/by color='+parseInt(t4-t3)+', offscreen/by color='+parseInt(t5-t4));
function drawIndividualPaths(players){
var len=players.length;
var PI2=Math.PI*2;
for(var i=0;i<len;i++){
var p=players[i];
ctx.beginPath();
ctx.arc(p.x,p.y,p.r,0,PI2);
ctx.fillStyle=p.color;
ctx.fill();
}
}
function drawColorPaths(players){
var len=players.length;
var PI2=Math.PI*2;
var clen=colors.length;
for(var c=0;c<clen;c++){
var color=colors[c];
ctx.fillStyle=color;
ctx.beginPath();
for(var i=0;i<len;i++){
var p=players[i];
if(p.color==color){
ctx.moveTo(p.x,p.y);
ctx.arc(p.x,p.y,p.r,0,PI2);
}
}
ctx.fill();
}
}
&#13;
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
&#13;
<h2>Please wait for perf tests to complete</h2>
<canvas id="canvas" width=300 height=300></canvas>
&#13;