使用类级嵌入访问MainTimeline符号

Jef*_*ard 2 air flash actionscript-3

这是场景:

我们拥有一个在Flash CS5.5中运行的创意团队,并生成包含图形元素和动作脚本代码的SWF资产,以及一个创建.as文件并构建"代码SWF"的工程团队.代码SWF文件必须加载或嵌入广告素材资源,并与其中的代码进行交互,以使我们的应用能够正常运行.

对于iOS移动开发,还有另一个考虑因素 - 由于Apple TOS,无法在iOS的AIR应用程序包中加载运行时代码(请参阅相关问题).因此,无法使用Loader在iOS环境中加载SWF并保留其代码.

将SWF嵌入到ActionScript文件中的标准方法会导致Loader直接将嵌入的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'
  });
}
Run Code Online (Sandbox Code Playgroud)

但是,这种嵌入机制在iOS设备上不起作用,因为每个Apple的TOS都不允许运行时代码 - 所有代码必须在编译时通过提前编译器(AOTCompiler)传递,并且嵌入在此的SWF中方式不符合这个标准.

问一下,我发现可以使用类级嵌入来解决这个问题,因为类级嵌入确实会通过编译器并导致iOS下的工作代码:

package
{
  import flash.display.MovieClip;

  [Embed(source="embed_test.swf", symbol="Symbol1")]
   public final dynamic class anim extends MovieClip { };
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但我不想在SWF中引用一个符号,我想要整个swf(也就是引用主时间轴),但是下面会导致编译错误:

package
{
  import flash.display.MovieClip;

  [Embed(source="embed_test.swf")]
   public final dynamic class anim extends MovieClip { };
}
Run Code Online (Sandbox Code Playgroud)

我还反编译了SWF,找到了主时间轴符号,并尝试了这个:

package
{
  import flash.display.MovieClip;

  [Embed(source="embed_test.swf", symbol="embed_test_fla.MainTimeline")]
   public final dynamic class anim extends MovieClip { };
}
Run Code Online (Sandbox Code Playgroud)

但是编译器坚持认为这个符号不存在.

由于我拥有许多SWF资产,因此我需要一个不涉及改变整个工作流程的解决方案(即进入每个FLA并进行更改).这应该是可能的,如果没有,这是Adobe应该解决的工作流问题.

所以我在这里被卡住 - 常规嵌入获得MainTimeline但在iOS中不起作用,类级嵌入在iOS中工作并且无法访问MainTimeline.

随意下载我的expample项目并使用它.

wel*_*rat 5

将对象放置在主时间轴上始终会在SWF文件中生成生成的代码:Flash IDE会为应用程序生成所有必需的代码,也就是说,它会在运行时创建要放置在舞台上的文档类的实例.但是,这是无法访问的代码,除非通过加载器对象加载SWF - 既不使用[嵌入],也不生成SWC将允许它.

我已经尝试过导出一个SWC,因为像@ 32bitkid我认为这是一种绕过限制的方法.事实证明,您可以实例化文档类,即使您没有显式声明文档类并让IDE自动生成它.但是,所有舞台实例都消失了.:(你也可以声明一个自定义的文档类,并将你的库对象放在舞台上使用addChild()- 然后一切正常.但是你在IDE的主时间轴上做的任何事情,你都无法访问.永远.

这是有道理的,太:该对象实际上阶段的情况下,放置在主时间轴上的实例.但是一旦你打电话new MyDocumentClass(),你就是在创建一个新实例 - 它还没有任何成员.

奇怪的是,所有这些对于任何库对象都应该是正确的 - 将对象实例放置在库对象时间线中也应该需要代码生成,不应该吗?- 但它实际上并不完全相同:你在图书馆对象的舞台上放置的任何内容仍然存在,并且在你打电话时可以访问new MyLibraryObject();.

所以.我看到你的项目工作的唯一方法是让你的设计师在每个FLA的库中创建一个唯一命名的"时间轴"MovieClip(或Sprite),并导出为ActionScript.(您不能总是使用"时间轴",因为在使用多个SWC时会出现命名冲突)然后使用此"时间轴"将任何必要的对象直接放在舞台上,添加帧代码等.在其中,设计人员可以完全按照他们习惯的方式工作,除了设备硬件和可用的API之外没有任何限制.唯一真正的区别是FLA本身的主时间轴上根本不存在任何东西.

然后,您可以使用SWC方法(这比手动生成[嵌入]代码要繁琐得多)并在主应用程序中实例化"时间轴"符号 - 一切都应该在您需要的地方.