Chr*_*ies 13 javascript performance html5-canvas
我正在调查使用HTML画布作为显示媒体制作游戏的可能性.为了完成我需要做的示例任务,我需要从多个等距区块构建游戏环境.当然,在2D工作意味着他们必须采用矩形包装,因此瓷砖之间有很大的重叠.
我已经够大了,这个问题的自然解决方案就是调用BitBltMasked.哦等等,不,HTML画布没有像BitBlt那样简单和令人愉悦的东西.似乎将像素数据转储到画布的唯一方法是使用drawImage(),它没有用于忽略alpha通道的有用绘图模式,或者使用具有数组中图像数据的ImageData对象.访问.是.界限.检查.和.因此.狗.慢.
好吧,这更像是一个咆哮而不是一个问题(W3C喜欢的东西往往会引起我的注意),但我真正想知道的是如何快速绘制画布?我发现很难放弃做100s drawImages()的感觉,每次抽奖都尊重alpha通道,这本身就是有罪的,并且可能使我的应用程序在许多浏览器中表现得像屁股.另一方面,实现BitBlt的唯一方法是在很大程度上依赖于浏览器使用类似热点的执行技术来使其快速运行.
有没有办法快速划分每个可能的实现,或者我只是忘记性能?
这是一个非常有趣的问题,您可以做一些有趣的事情来解决它。
首先,你应该知道drawImage可以接受一个Canvas,而不仅仅是一个图像。“子画布”甚至不需要在 DOM 中。这意味着您可以在一个画布上进行一些合成,然后将其绘制到另一个画布上。这开启了一个充满优化机会的世界,尤其是在等距瓷砖的背景下。
假设您有一个长 50 格、宽 50 格的区域(为了我自己的理智,我会说米)。您可以将该区域划分为 10x10 米的块。每个块都由它自己的 Canvas 表示。要绘制完整的场景,您只需将每个块的 Canvas 对象绘制到向用户显示的主画布上。如果只有四个块(一个 20x20m 的区域),您将只执行四个drawImage操作。
当然,这些单独的块中的每一个都需要呈现自己的画布。在块中什么都没有发生的游戏节拍上,您只需什么都不做:画布将保持不变,并会按照您的预期绘制。当某些事情发生变化时,您可以根据您的游戏执行以下操作之一:
drawImage每平方米一个,即 100),然后drawImage在块中每层执行一个操作(十)以重新绘制块的帆布。减少或增加块大小可能会提高或降低性能,具体取决于您对游戏环境进行的更新次数。可以进行进一步优化以消除drawImage对被遮挡的图块等的调用。drawImage每平方米块执行一个。如果更新了两个块,那么drawImage每个刻度只有 200 次调用(加上屏幕上可见的每个块 1 次调用)。如果您的游戏涉及的更新很少,那么减小块大小将进一步减少调用次数。requestAnimationFrame(正如您应该使用的那样),您只需要将块 Canvas 对象绘制到屏幕上。独立地,您可以在setTimeout循环等中执行游戏逻辑。然后,每个块都可以在帧之间的自己的滴答中更新,而不会影响性能。这也可以在 web worker 中完成,使用getImageData并将putImageData渲染块在需要更新时将其发送回主线程,尽管无缝地完成这项工作需要付出很多努力。您拥有的另一个选择是使用像 pixi.js 这样的库来使用 WebGL 渲染场景。即使对于 2D,它也会通过减少 CPU 需要完成的工作量并将其转移到 GPU 来提高性能。我强烈建议检查一下。
我知道GameJS具有 blit 操作,并且我当然假设任何其他 html5 游戏库也这样做(gameQuery、LimeJS 等)。我不知道这些包是否解决了您所关心的特定数组边界检查问题,但实际上它们的示例似乎在所有平台上都运行得很快。
您不应该假设什么加速是有意义的。例如,GameJS 开发人员报告说他要实现脏矩形跟踪,但事实证明现代浏览器会自动执行此操作 - link。
出于这个原因和其他原因,我建议在考虑速度之前先让一些东西发挥作用。另外,请利用绘图库,因为作者可能花了一些时间来优化性能。
我对此没有个人了解,但您可以查看 appMobi“直接画布”HTML 元素,据称该元素是普通画布的更快版本,链接。我很困惑这是否适用于所有浏览器或仅适用于 webkit 浏览器或仅适用于 appMobi 自己的特殊浏览器。
同样,如果没有对 Web 浏览器内部流程有非常深入的了解,您不应该假设加速的意义。关于“直接画布”的网页提到了一系列会减慢画布绘制速度的事情:“重排文本、映射热点、为参考链接创建索引等等。” 阿尔法混合和数组边界检查没有被提到是缓慢的主要原因!
| 归档时间: |
|
| 查看次数: |
6219 次 |
| 最近记录: |