2010-10-19 96 views
4

我正在制作游戏,并且出现了一些使用drawImage将一个画布绘制到另一个画布上的性能问题。根据Chrome的Profiler,我花了60%的时间在这一个drawImage调用和10%的clearRect上面...HTML/Canvas - 使用另一个画布绘制图像性能

目前的源画布大约是3000x3000(这是相当小的,我'd说),目标画布是1024x768。

我认为,不是绘制所有的瓷砖;墙壁等等每个循环(这给我15fps左右),它可能会更快地将它们全部绘制到屏幕外的画布上,然后将其绘制到我的主画布上,然后在顶部绘制实体等。这给了我〜30fps,但是......这是我用软件渲染获得的最好效果吗?

我的渲​​染循环基本上是:

ctx.clearRect(0, 0, 1024, 768); 

ctx.beginPath(); 
ctx.drawImage(map, cam.position.i, cam.position.j, 1024, 768, 0, 0, 1024, 768); 
ctx.closePath(); 

ctx.save(); 
ctx.translate(-cam.position.i, -cam.position.j); 
// draw entities, etc. 
ctx.restore(); 

我真的不能相信的事,除了开始使用的WebGL(以利用其硬件加速)或等待供应商来实现硬件加速2d上下文。尽管如此,我宁愿不做这些,所以任何输入都将不胜感激。

+2

我不知道beginPath方法和closePath适用的drawImage。 – kanaka 2010-10-19 16:32:26

+0

啊,我一直在用lineTo/moveTo和drawImage的路径。我刚刚删除它们,帧速率大致相同,但无论如何感谢。 – Xavura 2010-10-19 16:43:37

+2

3000x3000是庞大的,即使是1024x768在软件渲染方面已经很慢了,或者它耗尽了所有可以获得的CPU,根据我的经验,在硬件加速到达所有终端之前,没有多少可做。尽管如此,您可能会考虑使用基于HTML的方法来制作基于图块的游戏。 – 2010-10-19 17:04:04

回答

1

对每个“精灵”使用getImageData并在Javascript中保留对imageData数组的引用并使用putImageData呈现给目标画布可能会更快。

您仍然可以使用不可见源代码画布和每个tile/sprites上的getImageData来渲染您的精灵。它会使用更多的内存,但可能比使用源和目标画布的drawImage更快。

2

哇,这是一个大屏幕外屏。仅用于缓冲区的存储大约为36MB。

我会试图使用更小的离屏瓷砖,例如, 1024x124并在主画布上绘制可见的部分。为了节省内存,您最初只能创建可见的图块,然后在可见时生成其他图块。 (你可以处理,甚至更好的回收那些不再可见的)。

我不相信答案建议你使用putImageData将提供更好的性能,因为在这里提问的经验表明:why-is-putimagedata-so-slow