2

我是一名工程师,我们目前正在将我们的 Red5 + Flash 游戏移植到 Node.js + Easeljs html5 应用程序中。

基本上:这是一款棋盘游戏,而不是 rpg。图层系统意味着我们有多个画布,基于功能。例如,有一个带有图像的静态背景舞台。有一个仅用于计时器的层。

默认情况下,所有画布大小为 1920x1080,如果需要,我们会缩小以适应分辨率。

第一种方法使用了 kinetic.js,但是当游戏变得复杂时性能下降。然后我们切换到画架,因为它的抽象级别较低,所以我们可以决定如何实现更多的功能,而不仅仅是使用提供的健壮的功能。

我很乐观,但现在又开始显示缓慢,这就是为什么我想深入了解内部并进行微调。(当然在 Chrome 中一切都很好,Firefox 是问题,但游戏必须在所有现代浏览器上流畅运行)。

主要层(阶段)是地图,包含约 30 个容器,每个容器中都有一个复杂的自定义形状,约 10 个图像。容器正在侦听鼠标事件,例如鼠标悬停、退出、单击。目前,例如在鼠标悬停时,我用渐变填充形状。

不知何故,当我使用缓存时,就像 tuts 中的方式一样,性能变得更糟,所以我认为我搞砸了一些东西。

我收集了一些高级问题:

  1. 在所描述的情况下,我何时可以使用缓存以及如何使用?我已经在 init 上尝试过缓存,在填充其他颜色或渐变后使用 cacheUpdate,然后stage.update(). 没有影响。

  2. 如果我有一个静态的、从不改变的阶段缓存在该层上没有意义,对吧?

  3. 究竟stage.update()是做什么的?触发全层重绘?该文档提到了某种智能,如果更改然后重绘效果。

  4. 如果我想用新的颜色或渐变重新填充自定义形状,我必须完全重新绘制其图形,而不仅仅是使用 setFill 方法,对吗?

  5. 例如,在画架中,不可能只重绘一个容器,那么我怎么能设法不更新整个舞台,而只更新一个改变的容器呢?我认为我可以通过缓存来实现这一点,缓存所有容器只需更新更改的容器,但这种方式对我来说根本不起作用。

  6. 缓存位图图像有意义吗?如果容器中有自定义形状和图像,什么更好?缓存容器或仅缓存容器中的形状。

    我发现了一个奇怪的错误,或者至少是一个有趣的线索。我的画布层完全重叠。在下层,鼠标悬停监听运行良好,但点击不在同一个容器/对象上。

  7. 如何将单击事件传播到具有单击侦听器的重叠层?我已经使用简单的 DOM、jquery 进行了尝试,但事件对象与画布侦听器想要获得的对象相去甚远。

简而言之,我在尝试调整时已经成功玩过的方法和道具:cache(), updateCache(), update(), mouseEnabled, snapToPixel, clear(), autoClear, enableMouseOver, useRAF, setFPS().

任何答案,建议,起点表示赞赏。

更新:

这款免费的棋盘游戏是一款策略游戏,因此您面对的是一张拥有约 30 个领土的世界地图。自定义形状是区域,容器包含区域形状和应该在区域上方的图标。这个容器重叠是最小的。

一个示例鼠标事件是悬停效果。玩家在领土形状上导航,然后形状被重新着色、调整大小等,并出现一个包含该地点详细信息的气泡。

基本上,1-3 个容器的最大数量可以一次更改(除了初始化阶段 -> 此时全部)。不仅FF中的动画和重新着色很慢,而且侦听器延迟也很高。

我写了一个更改处理程序,所以我只stage.update()在修改阶段和动画运行的阶段(tweenjs)上打勾。

在我的第一种方法中,我将每个图像放入容器中,在游戏过程中至少需要一次,所以我只在图像(而不是矢量)上设置可见标志。

4

2 回答 2

0

2:如果你的层或阶段没有改变,不要为那个层调用 stage.update() (所以它不会被重新渲染,给我一个低得多的 cpu!)例如,保持一个全局的“stagechanged”变量并在发生变化时将其设置为 true:

createjs.Ticker.addEventListener("tick",
    function() {
        if (stagechanged)
        {
            stagechanged = false;
            stage.update();
        }
    });

(或者您是否已经使用它,如您的“更新”中所述?)

4:我找到了一种更新例如填充颜色的方法:)

contaier1.shape1.graphics._fillInstructions[0].params[1] = '#FFFFFF';

(使用 chrome 调试器查看 _fillInstructions 数组以查看哪个数组位置包含您的颜色)

5:我找到了一种只画一个容器的方法 :)

        //manual draw 1 component (!)
        var a = stage.canvas.getContext("2d");
        a.save();
        container1.updateContext(a);  //set position(x,y) on context
        container1.draw(a);
        a.restore();
于 2013-09-24T10:37:41.803 回答
0

关于缓存:有一些奇怪的缓存问题,不知何故性能会随着缓存矩形的某些大小而下降:CreateJS / EaselJS Strange Performance with certain size shapes

(2) 取决于您调用 stage.update() 的频率;

(3)

每次调用 update 方法时,stage 都会勾选任何暴露了 tick 方法的后代(例如 BitmapAnimation),并将其整个显示列表渲染到画布上。传递给 update 的任何参数都将传递给任何 onTick 处理程序。

=> Afaik 如果没有缓存,它会重新渲染所有内容

(4) 是的。

(5) 没有。(我不知道)

(6) 如果容器的内容不经常变化,我会缓存整个容器,否则每帧都会重新构建容器。

不过我有一个问题:为什么要使用多个画布?你用几个?我可以想象使用多个画布可能会减慢游戏速度。

你总共使用了多少个精灵?

于 2013-02-28T22:53:49.783 回答