flash - 使用类级嵌入访问 MainTimeline 符号

标签 flash actionscript-3 air

这是场景:

我们拥有一支在 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 并进行更改)的解决方案。这应该是可能的,如果不可能,这就是 Adob​​e 应该解决的工作流程问题。

所以我被困住了 - 常规嵌入获取 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/

相关文章:

java - 没有AspectJ的Java的Amazon SWF Flow框架

javascript - 如何检查 Flash 播放器是否安装在 Android 上

flash - 修复 Flash 的激进缓存

javascript - 在 Adob​​e Air 中将相机视频源附加到 html

Flash 视频在 IE7 中的所有其他内容之上播放

php - 类似于 Actionscript 中 PHP 的 __call()

actionscript-3 - 使用Flash/AS3录制内部音频

actionscript-3 - AS3 在添加到另一个 AS 类文件上的舞台时访问 MovieClip

android - 移动设备上的 StageVideo

flash - AIR:如何自定义 badge.swf 以启动 native 安装程序应用程序 (.exe)