多年前,我创建了一个简单的SWF,只是为了在各种浏览器上播放MP3文件。我公开了接口并从JavaScript调用它们。这一切都小而直白;您可以看到整个Guise.as
源代码。
我使用mtasc
编译了主类,它允许您为初始化代码指定一个主函数:
/**Main entry point.*/
static function main(mc)
{
这个工作正常,直到我想添加WAV支持。 Flash本身不支持WAV,因此我尝试添加library。但是库需要Flash 10而不能在mtasc
上编译,因此我下载了Flex 4.6并尝试使用mxmlc
。男孩,我的痛苦才刚刚开始。
我编译的SWF不再有效 - 即使对于MP3文件也是如此。我不知道从哪里开始发现问题,但我知道我有很多未解答的问题 - 也许其中一个是我的问题:
mxmlc
没有“主要入口点”的概念,但Flash只会创建“主要类”的实例,无论是什么。但是如何指定主类呢?如果我在命令行上使用mxmlc
引用我的类,那么该类是否会自动成为主类,还是绝对需要我的类在根(即no)包中?是否必须有一个特殊名称?Array.from=function(object:Object)
将对象转换为数组。当我处于严格模式时,这给了我一个错误 - 显然是因为它不喜欢我向Array
类对象添加静态方法。这仍然可以在非严格模式下工作吗?有什么问题?如果我将它转换为我班上的常规方法,它会起作用吗?Function.prototype.bind=function()
函数,这样当我有回调时,this
将被正确设置。这仍然有效吗?我可以将方法添加到Function
的原型中吗?positionTimeoutID=setTimeout(fireSoundPosition.bind(this), 1000)
之类的内容,如果没有bind(this)
,Flash会将正确的this
传递给我的回调方法吗?任何反馈都将不胜感激。我确信只有一两个小调整可以解决整个问题,但也许在社区的帮助下我不需要花几天时间阅读整本书并购买新的SDK只是为了重新编译我的SWF几个新电话......谢谢。
答案 0 :(得分:2)
我认为我不能回答你所有的问题,但我会尝试提供一些答案:
ActionScript 3是ActionScript 2的一个重大变化。它是一个完整的体系结构改造,不仅仅是一个小的更新,而且它不向后兼容,因此没有重写,通常很难调整非平凡的as2来编译如同3。它几乎就像一种全新的语言。所以最好退后一步,看看语言有什么变化,因为它很多。
最重要的是形式化的class inheritance,而不是典型的继承。
所以,当你从命令行编译时,你给它指向“主类”的路径:
mxmlc.exe "c:\dev\project\SomeClass.as"
SomeClass.as
看起来像这样:
package {
import flash.display.Sprite;
public class SomeClass extends Sprite {}
}
初始化后,flash将创建此类的实例并将其附加到舞台上。这与_root
的AS2概念类似。传递给-src
的{{1}}开关设置了支持此主类的其余类/包的路径。
因此,您的主要课程,无论您怎么称呼,都应该从mxmlc.exe
继承。
是。 “主类”的构造函数将是swf的入口点。
ActionScript 3类方法自动bound methods,这是对javascript的微妙改动。实际上,除了创建它的实例之外的任何其他上下文中都不可能调用类方法(即使您使用Sprite
或.call()
来尝试强制更改上下文)。例如,使用这个简单的类
.apply()
然后
public class SomeClass {
public function Worker() {
alert(this);
}
}
这四个函数调用将产生完全相同的结果,因为var cls:SomeClass = new SomeClass();
cls.Worker();
var func:Function = cls.Worker;
func();
func.call(this);
func.apply(undefined);
总是绑定到它来自的函数。
注意,这仅适用于类方法,并不适用于匿名函数/闭包。所以......
Worker()
......都不同
这取决于,如果它是一个类方法那么它将永远被绑定(参见上一节)。如果是闭包/匿名函数,那么是的,它仍然需要绑定指定var func:Function = function():void { alert(this); }
func();
func.call(cls);
func.call(undefined);
。
你可能想要获得flash debugging player。编译器应该附带fdb
,即flash命令行调试器。我们的想法是,当您在调试播放器中托管/运行应用程序时,可以将this
附加到实例和fdb
,以及设置断点和查看异常。
我将不得不调查这个,虽然我会想象“正确的” AS3解决方案,是从另一个类创建静态方法来执行此操作,而不是试图直接扩展trace()
。类似的东西:
Array
然后将其命名为:package {
public class ArrayHelpers {
public static From(object:Object):Array {
/* do work */
}
}
}
答案 1 :(得分:1)
感谢32bitkid的全面响应。我终于搞定了这个。只是为了填补剩余问题的答案,以下是我在这漫长的实验日中的一些经验。
首先,要获得一个主类,只需在mxmlc
命令行上指明该类。该类不必位于根包中。将启动内容放在类构造函数中。哦,从其他网站看来,课程可能需要扩展Sprite
或影片剪辑。
如32bitkit所示,不需要任何绑定内容。但请注意---自Flash 9以来,大部分API已发生变化。例如,ExternalInterface.call()
现在只需要两个参数,因为您不再需要传递上下文(例如this
)。 Sound API已完全改变。
尝试定义Array.from()
可能不起作用。 (在抛弃我不再需要的Function.prototype.bind()
之后我不需要它。)尝试增加现有的类,例如添加String.prototype.endsWith()
似乎也不起作用。
但也许我发现调试SWF最重要的事情是让我弄清楚问题非常重要:下载debug ActiveX Flash player并安装它用于IE。 (我只是推荐IE版本,因为这个练习的重点是我试图在IE上播放WAV文件--- 仅不支持WAV的主要浏览器Grumble发牢骚。)说真的,调试Flash播放器非常宝贵。独立调试播放器不支持ExternalInterface
。
哦,还有一种简单的方法来帮助调试?只需回调浏览器的日志记录例程,如下所示:
ExternalInterface.call("console.info", "Hello, world!");
它就像一个魅力!哦,最后一件事:在代码开始时立即打开它,当你从JavaScript调用SWF时,异常将返回并显示在浏览器的调试器中(反之亦然)!
ExternalInterface.marshallExceptions = true;
当我以为我只修改了几行代码时,我花了整整一天时间被迫转向ActionScript3和Flash 10以及Flex等。现在我至少把事情联系起来了,在很大程度上要归功于这里的反馈,明天我会跳回去试图找出为什么我can't get WAV files to play ---这是本练习的全部内容用。