如何缓存静态画布区域以获得性能

Posted

技术标签:

【中文标题】如何缓存静态画布区域以获得性能【英文标题】:How to cache static canvas areas in order to gain performance 【发布时间】:2015-09-24 03:42:17 【问题描述】:

我正在使用 createjs 库,我的游戏在背景上有一个大位图,以便以全高清分辨率填充窗口。在较低的分辨率下,我使用类似平移和扫描的方法。但是动作总是限制在画布的较小区域内。

所以我想知道是否有可能以及如何通过缓存静态区域或使用任何其他技术来获得性能。

为了论证,这里有一张图表来说明我的情况:

我已经尝试在这里使用 CSS 将背景图像放在画布元素后面:

How to center a canvas on top of a background image

但是 CSS 快把我逼疯了……所以请多多包涵…… :)

提前谢谢你!

【问题讨论】:

【参考方案1】:

在 EaselJS 中,每个 DisplayObject 都有一个缓存方法,这正是您想要的 - 它获取绘制的内容并放入屏幕外的画布上:http://www.createjs.com/docs/easeljs/classes/DisplayObject.html 之后,每次重绘时它都会从画布外获取图像数据(基本上它只是之后的 drawImage 调用)。

尝试仅缓存绘制区域 - 如果缓存空白区域,您将失去性能。但是,如果您的背景只是一个静态图像,您仍应将其保留为普通的 DOM/CSS 背景 - 缓存位图不会带来任何性能优势。

【讨论】:

我一直在使用 DisplayObject.cache(),我只是不知道缓存我的背景位图是否有意义。谢谢 随时发布您的 CSS 相关问题 - 很确定我们可以为您提供帮助。 ;-) 作为一种解决方法,您还可以为背景创建自己的画布,并且只绘制一次或更改。 ;-) 谢谢你。第二个画布不需要在背景上添加相同的 CSS 吗?我会尽快编辑我的问题。【参考方案2】:

我曾经有同样的想法,我想你要的是getImageData()和putImageDate()

image = context.getImageData(x,y,width,height);
context.putImageData(image,x,y);

但是,我仍然发现它的性能很差(抱歉,我不能再提供任何实际数字了),而获得更好性能的最好也是最流行的方法似乎是再做一个画布仅用于背景,或者,如果您真的只有静态背景图像,请使用您最初想要的纯 CSS。

context.drawImage() 也可以从另一个画布元素中绘制,也许您可​​以以某种方式利用它并创建不可见的“画布缓存”。但我仍然认为学习 CSS 比实现这样的东西更容易。

【讨论】:

感谢您的信息,看来我将不得不使用 CSS... :( EaselJS 中的缓存是离屏画布。一旦你缓存了一个对象,它就会被存储并代替实际内容绘制。【参考方案3】:

我不熟悉createjs,但您可以尝试仅在活动区域​​上绘制/清除。这样您就不会在每一帧中重绘非活动区域。 如果非活动区域不是完全静态的,您可以为它们使用单​​独的画布元素,并在该区域(非活动区域)发生更改后在主画布上绘制这些元素。呵呵

【讨论】:

以上是关于如何缓存静态画布区域以获得性能的主要内容,如果未能解决你的问题,请参考以下文章

缩放并旋转JavaFX画布的某个区域

为剪辑区域设置动画时清除画布时出现问题

重新填充画布擦除区域的区域

HTML5画布游戏静态实体元素

如何缩放到画布中心,而不是上下文中心

如何在 html 5 画布中删除区域的剪辑