如何在 EaselJS / CreateJS 中实例化大型 MovieClip 而不会降低帧速率

Posted

技术标签:

【中文标题】如何在 EaselJS / CreateJS 中实例化大型 MovieClip 而不会降低帧速率【英文标题】:How to instantiate large MovieClip without slowing framerate in EaselJS / CreateJS 【发布时间】:2016-09-12 11:37:54 【问题描述】:

一点上下文: 我在 Flash Pro / Adob​​e Animate 中创建了带有时间线动画的详细 MovieClip,并导出到 CreateJS / EaselJS 库。当我在运行时实例化它时,完成这个实例化需要比一帧或“滴答”更长的时间,并且动画播放会在前进到下一帧之前等待。这会在播放动画中造成打嗝。这是我的项目中经常出现的一个问题。如何在不简化 MovieClip 中的帧艺术的情况下克服这个问题?

代码:如果不清楚,这就是我要说的......

var instanceMC = new lib.bigMovieClip_mc(); // <-- LONG DELAY, OVER 1 TICK IN TIME

stage.addChild(instanceMC); // <-- from here on it seems to run smoothly
instanceMC.x = xPosition;
instanceMC.y = yPosition;
stage.update();

我的想法:

    如果异步实例化是一个选项,那将非常适合我的情况,但我不知道是否以及如何做到这一点。我看到它可以为 SpriteSheetBuilder 完成,这是一个类似但不同的情况(我不能使用 SpriteSheetBuilder,因为我有嵌套的独立控制的 MovieClips)。 我可以将 MovieClip 分解成更小的 MovieClip 并独立实例化它们,然后将它们组合在一起。这有点烦人,但可行。如果我这样做了,我会想听一个事件来完成每个实例化。这样的事件存在吗?我在文档中找不到。 加载JS。我对 LoadJS 很陌生。我检查了一下,它看起来像是用于管理下载,而不是其他初始化任务。但是,如果它可以将一系列大型实例化添加到加载队列(或者如果有类似的东西),并且在实例化过程中不阻止时间线播放,那将会很好。 多个画布和舞台?如果我添加带有自己舞台的第二个画布,我想每个舞台都有独立的帧标记,因此,通过在一个中实例化我的 MovieClip 并在另一个中播放我的动画,我可以将实例化和播放解耦。在我的特定情况下,应用程序的每个部分都非常独立,因此在使用中切换画布是可行的。我宁愿不处理将应用程序分成两部分的问题,但这似乎也是一种无需深入研究功能即可解决问题的直接方法。这在技术上是否可行,还是我做了一个错误的假设?

帮助:您可以建议什么方法(无论是否列出)可以解决我的问题?

【问题讨论】:

【参考方案1】:

首先,我希望有人添加比这更好的答案,我会很乐意更改所选答案。

我在一定程度上研究了各种选项,并了解到这实际上是一个根深蒂固的问题。它与浏览器的单线程特性有关,并且 UI 更新使用相同的线程并且必须等待轮到它们。请参阅:here、here、here 和 here。

从头开始设计库(如 CreateJS)以尽可能清除调用堆栈并利用回调队列可以避免在它们自己的操作期间锁定 UI(如 MovieClip 的实例化)。 (实际上这会暂停每一帧复杂操作的代码。)这是处理这种野兽的最佳方法。据我所知,MovieClips 的实例化在 CreateJS 中没有这种支持,尽管在运行时构建 spritesheets 有一个“异步”选项,当然,LoadJS 也是异步运行的(但目前不支持执行代码据我所知)。据推测,我的非常大的 MovieClip 会被认为超出了创作者的预期用途范围。

我的解决方案是在运行我的应用程序之前预加载所有影片剪辑并显示预加载器。这不是一个理想的解决方案,因为它有很长的等待时间,但它比我需要的替代方案更好(即更少的劳动力)。更好的方法可能是将有问题的 MovieClip 分解为不会独立引起问题的较小的 MovieClip,然后像这样实例化它们:

setTimeout( function() firstMovieClip = new lib.firstMovieClip(); ,0);
setTimeout( function() secondMovieClip = new lib.secondMovieClip(); ,0);
 and so on....

这导致它们不直接入栈,而是进入回调队列。这反过来又允许 UI 在这些较小的实例之间进行更新,因为堆栈已清除。

对于它的价值,还有一些选项可以在浏览器中使用 Web Worker 运行额外的线程。它不适用于我的目的,因为这些网络工作者中的对象无法移动到 UI。对于具有简单结果(如数字)的复杂计算,这将是一个很好的解决方案。

【讨论】:

以上是关于如何在 EaselJS / CreateJS 中实例化大型 MovieClip 而不会降低帧速率的主要内容,如果未能解决你的问题,请参考以下文章

Createjs学习心得之使用EaselJs实现拖拽效果

CreateJS / EaselJS 具有特定尺寸形状的奇怪性能

canvas 动画库 CreateJs 之 EaselJS(上篇)

canvas 动画库 CreateJs 之 EaselJS(上篇)

我怎样才能用easeljs-0.8.0.js画一条线?(createJs)

如何使用 EaselJS 在位图上绘制/绘制线条?