如何加快在画布上绘制瓷砖
How to speed up drawing tiles on canvas?
我试着写一个等距贴图游戏引擎,有这个代码的速度问题:
$(function() {
var canvas = document.getElementById('GameCanvas');
var context = document.getElementById('GameCanvas').getContext('2d');
var imgObj = new Image();
imgObj.src = 'img/sand_surface.png';
var Game = {
tileScaleX: 64,
tileScaleY: 32,
FPSLimit: 50, // max allowed framerate
realFPS: 0, // real framerate
init: function() {
this.cycle(); // main animation loop
},
cycle: function() {
this.debug(); // print framerate
startTime = new Date; // start fps time
this.clear(); // celar canvas
this.draw(); // draw frame
endTime = new Date; // end fps time
setTimeout(function() {
endTimeWithSleep = new Date; // end fps time with sleep
this.realFPS = 1000 / (endTimeWithSleep - startTime);
this.cycle(); // repeat animation loop
}.bind(this), (1000 / this.FPSLimit) - (endTime - startTime));
},
debug: function() {
$('.DebugScreen').html('<b>FPS:</b> ' + Math.round(this.realFPS*1)/1);
},
clear: function() {
canvas.width = canvas.width; // clear canvas
},
draw: function() {
Location.drawSurface(); // draw tiles
},
}
var Location = {
width: 60,
height: 120,
drawSurface: function() {
for (y = 0; y < this.height; y++) {
for (x = 0; x < this.width; x++) {
if ((y % 2) == 0) {
rowLeftPadding = 0;
} else {
rowLeftPadding = Game.tileScaleX / 2;
}
context.drawImage(imgObj, (x * Game.tileScaleX + rowLeftPadding), y * (Game.tileScaleY / 2), Game.tileScaleX, Game.tileScaleY);
}
}
},
}
Game.init(); // start game
});
如果我设置了Location。宽度和位置。高度到低的数字,然后它运行速度快(50 fps),但在这个例子中(Location.width = 60
, Location.height = 120
)帧率是10 fps,我需要50 fps,你有什么建议如何加快这个脚本?
1)在我看来,你在画每一块瓷砖,即使它们不在视野中。使用"剪切"。在调用context.drawImage()
之前,您需要计算tile是否在视图中。
2)如果你的场景是静态的,提前计算它(尽可能多)。然而,创建一个巨大的图像也不是一个好主意,你宁愿预先计算一些大块(即512x512)。
3)在一些浏览器中,据说你可以得到更好的帧率,如果不是使用'setTimeout()',你使用requestAnimationFrame(我也发现这篇文章很有趣)。
4)调整大小/缩放可能会影响性能(特别是在较旧的浏览器或硬件)。如果你的贴图已经是32x64,你可以使用drawImage()只有3个参数,避免调整大小(不适用,如果你需要缩放实现缩放效果或类似)。
除了@jjmontes的优秀答案,你还应该在游戏中使用多个画布元素,并且只更新画布中已更改的部分。现在你每次都在清理和重画所有的东西。
在我这边弄乱了你的代码之后,我得到了45-50之间的代码。一个建议是不要使用jQuery,也不要修改元素的html
来显示fps。我还修改了你的演示,使其最大帧数为100帧,它的帧数约为70帧/秒。
您也可以尝试缓存调整大小的图像并使用它,您应该会看到性能的提高。在下面的演示中,我将调整大小的图像缓存在临时画布上,并使用它来代替。
实时演示(我不想为图像实现onload
,所以如果它是一个白屏,就再次点击运行)
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 有没有一个javascript图形绘制库可以进行气球树布局
- 使用相同的数据集绘制各种符号
- 使用onclick绘制SVG路径
- 在谷歌地图上绘制位置数据库
- 用chart.js绘制条形图
- “可绘制地图”设置地图选项“纬度-经度”
- 多维数据集网格未在指定的分区中绘制
- 使用谷歌图表在x轴上绘制日期
- 使用fabric.js从矩形区域获取对象,并将该区域绘制到画布上
- 如何在React Native中绘制图形
- 画布中绘制的矩形区域的弹出工具提示
- 如何在OpenLayers中获取动态绘制的多边形的坐标
- 画布:逐像素绘制图像并请求动画帧计时
- D3从嵌套的JSON中绘制第二个圆环图
- 如何用d3.js绘制折线图
- 在WebGL中绘制多个二维图像
- JSXGraph:如何绘制带有箭头和无点标记的矢量
- HTML5,在加载时将像素渲染为图像,以加快绘制时间
- 如何加快在画布上绘制瓷砖