Flash 使用类级嵌入访问主时间线符号

Flash 使用类级嵌入访问主时间线符号,flash,actionscript-3,air,Flash,Actionscript 3,Air,以下是场景: 我们有一个创造性的团队,在FlashCS5.5中运行,并生产包含图形元素和actionscript代码的SWF资产,还有一个工程团队,负责编写.as文件和构建SWF代码。代码SWF文件必须加载或嵌入创意资产,并与其中的代码交互,以使我们的应用程序正常运行 对于iOS移动开发,还有另一个考虑因素——由于Apple TOS,无法在iOS的AIR应用程序包中加载运行时代码。因此,不可能使用加载程序在iOS环境中加载SWF并保留其代码 以标准方式将SWF嵌入ActionScript文件会导

以下是场景:

我们有一个创造性的团队,在FlashCS5.5中运行,并生产包含图形元素和actionscript代码的SWF资产,还有一个工程团队,负责编写.as文件和构建SWF代码。代码SWF文件必须加载或嵌入创意资产,并与其中的代码交互,以使我们的应用程序正常运行

对于iOS移动开发,还有另一个考虑因素——由于Apple TOS,无法在iOS的AIR应用程序包中加载运行时代码。因此,不可能使用加载程序在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设备上不起作用,因为苹果的TOS不允许运行时代码——所有代码都必须在编译时通过提前编译器,并且以这种方式嵌入的SWF不符合此标准

询问周围的人,我认为可以使用类级嵌入来解决这个问题,因为类级嵌入确实会经过编译器,并会导致在iOS下工作的代码:

package
{
  import flash.display.MovieClip;

  [Embed(source="embed_test.swf", symbol="Symbol1")]
   public final dynamic class anim extends MovieClip { };
}
这很好,但我不想引用SWF中的符号,我希望整个SWF aka引用主时间线,但以下结果会导致编译器错误:

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应该解决的工作流问题

所以这里我被卡住了-普通的嵌入程序可以获取主时间线,但不能在iOS中工作,类级别的嵌入程序可以在iOS中工作,不能访问主时间线


您可以随意使用它。

将对象放置在主时间轴上总是会在SWF文件中生成生成的代码:Flash IDE生成应用程序运行所需的所有代码,也就是说,它会创建文档类的实例,以便在运行时放置在后台。然而,这是无法访问的代码,除非SWF是通过loader对象加载的——使用[Embed]或生成SWC都不允许

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

这也有道理:对象实际上是放置在主时间轴实例上的阶段实例。但是一旦你调用了新的MyDocumentClass,你就创建了一个新的实例——它还没有任何成员

奇怪的是,所有这些对于任何库对象都应该是正确的——在库对象时间线中放置对象实例也应该需要生成代码,不是吗但事实上根本不一样:当您调用新的MyLibraryObject;时,您在舞台上放置在library对象中的任何内容都将仍然存在并可以访问

所以。我认为让你的项目工作的唯一方法是让你的设计师在每个FLA的库中创建一个唯一命名的时间线MovieClip或Sprite,并将其导出到ActionScript。您不能总是使用时间线,因为在使用多个SWC时,您可能会遇到命名冲突。该时间线用于将任何必要的对象直接放置在舞台上,添加帧代码等。在时间线中,设计师可以完全按照他们习惯的方式工作,除设备硬件和可用API外,无任何限制。唯一真正的区别是,佛罗里达州本身的主要时间线上永远不可能存在任何东西


然后,您可以使用SWC方法,这比手动生成[Embed]代码并从主应用程序中实例化时间线符号要简单得多——一切都应该在您需要的地方进行。

我将发布我自己的解决方法,以防此问题发生:

这里有一个更详细的回复:

我已经创建了一个工具,通过将嵌入式SWF合并到主SWF中来解决这个问题。通过这种方式,嵌入被AOT编译并转换为objective-c代码,因此我得到了我的资产的一个实例——主时间线,并且资产的代码被正确地交叉编译以在iOS设备上工作

它的工作原理是使用如下的嵌入:

[Embed(source="GameLevel.swf")]
  private var GameLevel:Class;

public function main():void
{
  var my_level:* = new GameLevel();
  addChild(my_level);
}
在这种情况下,如果游戏级别 .swf中有代码,它通常在iOS中不起作用,因为新的gameLevel将创建一个加载程序并解释swf字节码。但是,如果您首先通过我的名为SWFMerge的工具运行上述SWF,它将获取嵌入的SWF并将其合并到根SWF中。然后ADT将把你的主swf(包括嵌入的代码)编译成objective-C,它将在iOS上运行,注意:新的gameLevel现在直接生成你的资产实例,而不是加载程序

SWFMerge工具位于此处:

请在评论中告诉我此解决方案是否适用于您,或者您是否有问题


我要补充的是,使用SWC工作流更好,并且得到官方支持,但是在紧要关头,如果您没有原始的FLA源文件,或者只是想快速使用包含代码的现有资产,这种变通方法非常有用。

您到底想做什么?root和stage属性应足以访问主时间线。无需在iOS项目或任何其他项目中使用加载程序。澄清了为什么我要嵌入SWF的问题-我需要访问嵌入资产SWF的主时间线,而不是我自己的代码生成SWF。你是否尝试过为其他库制作SWC,然后只是实例化链接的类?SWC确实有效,但是我有大量的资产被编译成主权财富基金,所以我想找到一个嵌入它们的解决方案。当你使用TLF文本字段时,这个问题就会发生。使用常规文本字段时,可以访问SWF的符号。然后你可以嵌入并使用它们。我会投票支持这一点,因为使用SWC和库对象是正确的方法。但不幸的是,我们的团队多年来一直在使用SWF工作流,所以我已经编译了许多SWF资产,我想按原样使用它们。也许这根本不可能,但它应该是。这似乎是AdobeAIR平台独立性声明中的一个大漏洞,在这一点上,AdobeAIR的平台独立性伤害最大——毫无明显原因地强制工作流更改。Adobe,1个常规的[Embeddes]应该由AOT编译器处理以满足iOS TOS,因为它们在编译时是代码库的一部分,或者应该允许2类级别的嵌入以主时间线为目标。我同意-你应该向Adobe提交一个bug。但是,更改原始FLA不应该是一个无法解决的问题-如果您仍然可以访问它们:创建一个新的空MovieClip->选择主时间线中的所有帧,而不是舞台上的所有对象!,使用剪切帧->将帧粘贴到新剪辑的时间线中。这甚至应该保留图层名称。