绘制多个任意行是过于昂贵的EaselJS

时间:2014-09-02 03:46:47

标签: javascript html5 performance easeljs tween.js

我正在使用EaselJS编写一个HTML5 2D“游戏”,它看起来像一个行星/重力模拟器,我决定跟踪每个行星移动时跟随行星的运动/轨道。这是一个快速的GIF演示:

Demonstration of what I want

问题是:如果我在每个刻度处创建一条线,画布变得非常慢(因为它在每个刻度处绘制了很多行,这很昂贵),所以我将昂贵的代码移到了setInterval循环之间的间隔为250毫秒,问题仍然存在,因为当有很多形状时,它会为每个循环创建大量的行。另外,如果我只是在每个循环之间添加更多时间,结果将开始显示...... Minecraft-ish。

Demonstration of 750ms intervals between each loop

我对如何解决这个问题一无所知,因为我能想到的一切都包括在每个循环中创建大量的行。我已经尝试过使用缓存,但是缓存这些细微的线条只会导致它们在最终的缓存图像中消失,而且由于问题不在于更新线条,而是创建新的线条,我认为缓存对我没有任何作用。 / p>

以下是相关代码:

setInterval(function() {
    allObjs.forEach(function(obj1) {
        if (typeof obj1.xpast !== "undefined" || typeof obj1.ypast !== "undefined") {
            var trail = new createjs.Shape();
            trail.graphics.s("#fff").ss(1, "round").moveTo(obj1.xpast + .5, obj1.ypast + .5).lineTo(obj1.x + .5, obj1.y + .5);
            trail.alpha = 0.25;
            stage.addChild(trail);
            setTimeout(function() {
                createjs.Tween.get(trail).to({
                    alpha: 0
                }, 1000).call(function() {
                    stage.removeChild(trail);
                });
            }, 10000);
        }
        obj1.xpast = obj1.x;
        obj1.ypast = obj1.y;
    });
}, 750);

不幸的是,我目前无法将我的代码放在JSFiddle中。

1 个答案:

答案 0 :(得分:3)

当每帧重绘画布(并清除它反映不断变化的内容)时,矢量线会非常快速地加起来。这是因为每帧都重绘了Graphics指令。画布上的矢量不是硬件加速的,因此当你接近很多行时,使用这种方法会非常慢。

最好的方法是缓存矢量,然后只绘制新的内容。缓存它时,会在幕后创建一个新的canvas元素,并用它来代替实际的图形。这意味着您可以根据需要使其变得复杂,而不会改变性能。

  • 以您需要的尺寸(可能是画布尺寸?)
  • 缓存形状
  • 为该框架绘制新图形
  • 更新缓存(将图形内容绘制到现有缓存中)
  • 下次清除图片

在GitHub上有一个例子:

希望这有帮助!