这是场景:
我们拥有一支在 Flash CS5.5 中运行并生成包含图形元素和 ActionScript 代码的 SWF 资源的创意团队,以及一支编写 .as 文件并构建“代码 SWF”的工程团队。代码 SWF 文件必须加载或嵌入创意资源并与其中的代码交互,以便我们的应用程序正常运行。
对于 iOS 移动开发,还有另一个考虑因素 - 由于 Apple TOS,无法在 iOS 的 AIR 应用程序包中加载运行时代码(请参阅 related question )。因此,不可能使用 Loader 在 iOS 环境中加载 SWF 并保留其代码。
以标准方式将 SWF 嵌入到 ActionScript 文件中会产生一个将嵌入的 SWF 直接作为字节加载的加载器。这将导致对顶层主时间线的访问,如下所示:
[Embed(source="embed_test.swf")]
private var no_aot_support:Class;
public function main():void
{
var no_ios:* = new no_aot_support();
addChild(no_ios);
no_ios.addEventListener(Event.COMPLETE, function():void {
var timeline:MovieClip = no_ios.getChildAt(0).getChildAt(0);
trace(timeline.foo); // foo variable exists, output is 'blah'
});
}
但是,这种嵌入机制在 iOS 设备上不起作用,因为 Apple 的 TOS 不允许运行时代码 - 所有代码都必须在编译时通过提前编译器 (AOTCompiler),并且 SWF以这种方式嵌入不符合此标准。
打听了一下,我found可以使用类级嵌入来解决这个问题,因为类级嵌入确实会通过编译器,并会在 iOS 下产生工作代码:
package
{
import flash.display.MovieClip;
[Embed(source="embed_test.swf", symbol="Symbol1")]
public final dynamic class anim extends MovieClip { };
}
这工作正常,但我不想引用 SWF 中的符号,我想要整个 swf(也称为引用主时间轴),但以下结果会导致编译器错误:
package
{
import flash.display.MovieClip;
[Embed(source="embed_test.swf")]
public final dynamic class anim extends MovieClip { };
}
我还反编译了 SWF,找到了主时间线符号,并尝试了以下操作:
package
{
import flash.display.MovieClip;
[Embed(source="embed_test.swf", symbol="embed_test_fla.MainTimeline")]
public final dynamic class anim extends MovieClip { };
}
但是编译器坚持认为这个符号不存在。
由于我有很多很多 SWF 资源,因此我需要一个不涉及更改整个工作流程(即进入每个 FLA 并进行更改)的解决方案。这应该是可能的,如果不可能,这就是 Adobe 应该解决的工作流程问题。
所以我被困住了 - 常规嵌入获取 MainTimeline 但在 iOS 中不起作用,类级嵌入在 iOS 中工作但无法访问 MainTimeline。
欢迎联系download my expample project并玩这个。
最佳答案
将对象放置在主时间轴上始终会生成 SWF 文件中的生成代码:Flash IDE 会生成应用程序运行所需的所有代码,即创建文档类的实例在运行时放置在舞台上。然而,这是无法访问的代码,除非通过加载器对象加载 SWF - 无论使用 [Embed] 还是生成 SWC 都不允许这样做。
我尝试过导出 SWC,因为像 @32bitkid 一样,我相信这是绕过限制的一种方法。事实证明,您可以实例化文档类,即使您没有显式声明文档类并让 IDE 自动生成它。但遗憾的是,所有舞台实例都消失了。 :( 您还可以声明一个自定义文档类并使用 addChild()
将您的库对象放置在舞台上 - 然后一切正常。但是您在 IDE 的主时间轴上执行的任何操作,你永远无法访问。
这也是有道理的:这些对象实际上是放置在主时间轴实例上的舞台实例。但是,一旦您调用 new MyDocumentClass()
,您就会创建一个新实例 - 该实例还没有任何成员。
奇怪的是,所有这些对于任何库对象都应该是正确的 - 将对象实例放置在库对象时间线中也应该需要代码生成,不是吗? - 但实际上根本不一样:您在库对象中放置在舞台上的任何内容都将仍然存在,并且当您调用new MyLibraryObject();时可以访问
.
所以。我认为让您的项目发挥作用的唯一方法是让您的设计人员在每个 FLA 库中创建一个唯一命名的“时间轴”MovieClip(或 Sprite),并将其导出到 ActionScript。 (您不能总是使用“时间轴”,因为这样在使用多个 SWC 时就会出现命名冲突)然后,该“时间轴”用于将任何必要的对象直接放置在舞台上、添加帧代码等。在其中,设计人员可以完全按照他们习惯的方式工作,除了设备硬件和可用的 API 之外没有任何限制。唯一真正的区别是 FLA 本身的主时间线上不可能存在任何东西。
然后,您可以使用 SWC 方法(这比手动生成 [嵌入] 代码要简单得多)并在主应用程序中实例化“时间轴”符号 - 一切都应该在您需要的地方。
关于flash - 使用类级嵌入访问 MainTimeline 符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8915924/