1

我正在编写一个通用图形引擎,该引擎将使用 molehill 优势在 FP11 上工作,也可以使用旧软件 blitting 在 FP10 上工作。

所以,我在想实现这一目标的最佳方法是什么?

首先我想如果我为 FP11 编译 swf 并且如果播放器的版本不是 11 则不使用新类,一切都会正常工作。但是我错了。令我惊讶的是,如果我使用导入的 FP11 库运行代码,即使没有调用它们,我也会收到“VerifyError:错误 #1014。找不到类 flash.display3D::Context3D”错误。

我认为只有当我尝试访问缺席的课程时 FP 才会抛出此消息,但这是不对的。就在我尝试运行 .swf 时它会引发错误

那么,有什么办法可以做到吗?我曾想过使用预加载器根据版本加载不同的 SWF,但维护和编译 2 个不同的 SWF 非常令人困惑。

还有其他方法吗?

4

3 回答 3

2

如果您使用的是 Flash(而不是 Flex 或其他工具),您唯一的选择可能是条件编译,我相信。当我不得不在 CS5 中处理这个问题时,我找不到其他任何东西。

我最终做的是为各种配置定义了几个常量,然后编译了几个版本的 .swf。我根据浏览器中的播放器检测代码加载了正确的 .swf 文件。如果你想把你的 .swf 放在 Newgrounds 等地方,那真是一团糟。

于 2011-12-08T19:08:40.263 回答
1

flash api 不向前兼容。如果你想要一个flash 11 api,你需要制作一个flash 11+ swf。这样做的原因是 swf 10 可以愉快地创建它自己的 Stage3D 类。如果它突然与 swf 11 中的内置类发生冲突,这将破坏向后兼容性。所以你只能有一个,向后或向前兼容性。

于 2012-01-29T10:55:08.800 回答
1

编辑

抱歉,我没有注意到您不想支持不同版本的库。在这种情况下,没有办法——当 FP 处理 SWF 的字节码并找到未知引用时,它会抛出 VerifyError。当然,你可以使用getDefinitionByName()和动态访问,但是它慢。

为了最大限度地减少单独支持的代码量,您可以使用具有主要功能的 SWC 和具有版本相关功能的 SWF,因此在初始化阶段,您的 lib 的主类将检查 FP 版本并加载适当的 SWF。


这称为动态链接,有一种方法:

  1. 创建所有播放器版本相关功能的接口 ( public interface MyInterface...)。此接口不应包含对版本相关 API 的任何引用。将此接口(它可能只是单个 .as 文件)编译成 SWC(顺其自然lib-intf.swc)。

  2. 创建此接口的两个独立实现;第一个将使用新的 API,第二个不会(它可能只是一个占位符,但也可能是一个替代实现)。稍后我们需要将这些实现编译成 SWF,因此我们需要扩展Sprite. 最简单的方法是让这些主类实现我们的接口(即public class MyImplementationA extends Sprite implements MyInterface...和 相同MyImplementationB)。它们只是空Sprites的,但它们将包含接口方法。

  3. 将这两个实现独立编译成单独的 SW F (lib-a.swflib-b.swf)。编译时,lib-intf.swc作为外部库包含(-external-library-path编译器参数或 IDE 中的“外部”链接类型)。

  4. 现在,在编译根应用程序时,lib-intf.swc像往常一样包含库(-library-path编译器参数或 IDE 中的“合并到代码”链接类型)。根本不包括与版本相关的类。因此,在根应用程序中,您将只引用与版本无关的接口。当您的应用程序启动时,检查 FP 版本,并根据它使用 Loader 类加载适当的 SWF。您必须将其加载到主应用程序域中,而不是它的子域(这是默认选项;更多详细信息)。

  5. 加载 SWF 后,将其转换为界面:var versionDependentImpl:MyInterface = loader.content as MyInterface. 请记住,我们的 SWF 的主要类实现了MyInterface,所以这个转换可以工作。

  6. 就是这样——现在你可以使用你的实现了:versionDependentImpl.someMethod(). 当然,someMethod应该定义在MyInterface.

因此,这里的技巧是从 SWF 文件动态加载实现。虽然根应用程序对这个 SWF 中的类一无所知,但我们可以使用它的主类的方法,因为我们让它实现了一个我们已经编译到根应用程序中的接口。

这种方法是可扩展的:例如,您可以定义具有返回其他接口的方法的主接口。您甚至可以将实现之间共享的具体类包含到lib-intf.swc中,只要它们不使用与版本相关的 API。

于 2013-01-23T11:20:50.150 回答