[英]Migrating to Flex mxmlc from ActionScript 2 mtasc
几年前,我创建了一个很小的简单SWF文件,仅用于在各种浏览器上播放MP3文件。 我公开了接口,并通过JavaScript对其进行了调用。 一切都小而直接。 您可以查看整个Guise.as
源代码。
我使用mtasc
编译了主类,该类允许您为初始化代码指定一个主函数:
/**Main entry point.*/
static function main(mc)
{
在我想添加WAV支持之前,这一直很好。 Flash本身不支持WAV,因此我尝试添加一个库 。 但是该库需要Flash 10,并且无法在mtasc
编译,因此我下载了Flex 4.6并尝试使用mxmlc
。 男孩,我的痛苦才刚刚开始。
我编译的SWF不再有效-甚至对于MP3文件也是如此。 我不知道从哪里开始发现问题,但我知道我有很多未解决的问题-也许其中一个是我的问题:
mxmlc
没有“主入口点”的概念,但是Flash只会创建“主类”的实例,无论它是什么。 但是,如何指定主类? 如果我在命令行上使用mxmlc
引用我的类,那么该类将自动成为主类,还是绝对要求我的类位于根包中(即,否)? 它必须有一个特殊的名字吗? Array.from=function(object:Object)
将对象转换为数组。 当我处于严格模式时,这给了我一个错误-显然是因为它不喜欢我向Array
类对象添加静态方法。 仍然可以在非严格模式下工作吗? 有什么问题? 如果我将其转换为类的普通方法,是否可以使用? Function.prototype.bind=function()
函数,以便在有回调时可以正确设置this
函数。 这仍然有效吗? 我可以在Function
的原型中添加方法吗? positionTimeoutID=setTimeout(fireSoundPosition.bind(this), 1000)
,而没有bind(this)
,Flash是否会将正确的this
传递给我的回调方法? 对于任何反馈,我们都表示感谢。 我敢肯定,只有一两个小小的调整就可以解决问题,但也许在社区的一点帮助下,我不必花几天时间阅读整本书并购买新的SDK,只需用几个新电话...谢谢。
我认为我无法回答您的所有问题,但我会尝试提供一些答案:
ActionScript 3是对ActionScript 2的实质性更改。它是完整的体系结构检修,不仅是次要更新,而且也不向后兼容,因此缺少重新编写功能,通常很难调整非平凡的as2以将其编译为as3。 这几乎就像是一种全新的语言。 因此,最好退后一步,看看语言中发生了什么变化,因为变化很多。
最大的事情是形式化类继承 ,而不是原型继承。
因此,当您从命令行进行编译时,将为其提供“主类”的路径:
mxmlc.exe "c:\\dev\\project\\SomeClass.as"
与SomeClass.as
看起来像这样:
package {
import flash.display.Sprite;
public class SomeClass extends Sprite {}
}
初始化后,Flash将创建此类的实例并将其附加到舞台上。 这将类似于_root
的AS2概念。 传递给mxmlc.exe
的-src
开关将路径设置为支持该主类的其余类/软件包。
这样,无论您叫什么主类,它都应该继承自Sprite
。
是。 “主类”的构造函数将是swf的入口点。
ActionScript 3类方法是自动绑定的方法 ,与javascript相比有微妙的变化。 事实上,它不可能调用任何其它方面比从它被创造在哪里(即使您使用该实例类方法.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);
...都是不同的
这取决于,如果它是一个类方法,那么它将始终被绑定(请参阅最后一节)。 如果是闭包/匿名函数,则可以,它仍然需要绑定以指定this
。
您可能需要获取Flash调试播放器 。 并且编译器应该附带有fdb
(Flash命令行调试器)。 这个想法是,当您在调试播放器中托管/运行应用程序时,可以将fdb
附加到实例和trace()
,以及设置断点和查看异常。
我将不得不研究这个问题,尽管我想“合适的” AS3解决方案将是在另一个类的基础上创建一个静态方法来执行此操作,而不是尝试直接扩展Array
。 就像是:
package {
public class ArrayHelpers {
public static From(object:Object):Array {
/* do work */
}
}
}
然后将其称为: ArrayHelpers.From(whatever);
感谢32bitkid的全面答复。 我终于完成了这项工作。 只是为了回答其余问题,这是我在这一漫长的实验中的一些经验。
首先,要获取主类,只需在mxmlc
命令行上指示该类。 该类不必位于根包中。 将启动内容放入类构造函数中。 哦,从其他网站上看来,此类可能需要扩展Sprite
或影片剪辑。
如32bitkit所示,不需要任何绑定东西。 但是请注意-自Flash 9以来,许多API都已更改。例如, ExternalInterface.call()
现在仅接受两个参数,因为您不再需要传递上下文(例如this
)。 声音API已完全更改。
尝试定义Array.from()
可能无法正常工作。 (在抛弃了我不再需要的Function.prototype.bind()
,我不再需要它。)尝试扩展现有类,例如添加String.prototype.endsWith()
似乎也不起作用。
但是,也许我发现的有关调试SWF的最重要的事情最终使我能够找出问题非常重要:下载调试ActiveX Flash Player并将其安装到IE。 (我只推荐IE版本,因为本练习的重点是我试图让WAV文件在IE上播放-IE是唯一不支持WAV文件的主流浏览器。 ,调试Flash播放器非常宝贵。 独立调试播放器不支持ExternalInterface
。
哦,这是帮助调试的一种简便方法吗? 只需调用浏览器的日志记录例程,如下所示:
ExternalInterface.call("console.info", "Hello, world!");
它就像一个魅力! 哦,最后一件事:在代码开始时立即将其打开,然后当您从JavaScript调用SWF时,异常会再次出现并显示在浏览器的调试器中(反之亦然)!
ExternalInterface.marshallExceptions = true;
当我以为只修改几行代码时,我整天都不得不升级到ActionScript3,Flash 10和Flex等。 现在我至少已经连接好了东西,这在很大程度上要感谢这里的反馈,明天我将跳回去并尝试找出为什么我无法播放WAV文件 ---这就是重点开始做运动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.