1

几年前,我创建了一个小巧简单的 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类对象添加静态方法。这仍然可以在非严格模式下工作吗?有什么问题?如果我将它转换为我课堂上的普通方法,它会起作用吗?
  • 正如我习惯在“真正的” JavaScript 中做的那样,我添加了一个Function.prototype.bind=function()函数,以便在我有回调时this正确设置。这仍然有效吗?我可以在原型中添加方法Function吗?
  • 我还需要绑定上下文吗?如果我调用类似positionTimeoutID=setTimeout(fireSoundPosition.bind(this), 1000), without的东西bind(this),Flash 会将正确的值传递this给我的回调方法吗?
  • Flex 编译器抱怨几个 API 方法发生了变化,所以也许修改我的调用改变了一些东西,我不理解新的 API。有没有办法调试这个 SWF?写入浏览器控制台?哔?任何事物?无需从 Adob​​e 购买一些大型 IDE 之类的?

对于任何反馈,我们都表示感谢。我敢肯定,只有一两个小调整会影响整个事情,但也许在社区的帮助下,我不必花几天时间阅读整本书和购买新的 SDK 来重新编译我的 SWF几个新电话...谢谢。

4

2 回答 2

2

我不认为我可以回答你所有的问题,但我会尝试提供一些答案:

ActionScript 3 是对 ActionScript 2 的重大更改。它是一个完整的架构大修,不仅仅是一个小更新,而且它不向后兼容,所以没有重写,通常很难调整非平凡的 as2 以编译为 as3。它几乎就像一门全新的语言。所以最好退后一步,看看语言有什么变化,因为它很多。

最大的事情是形式化的类继承,而不是原型继承。

  • “Flash 将简单地创建一个‘主类’的实例,不管它是什么。”

所以,当你从命令行编译时,你给它“主类”的路径:

mxmlc.exe "c:\dev\project\SomeClass.as"

SomeClass.as看起来像这样:

package {
    import flash.display.Sprite;
    public class SomeClass extends Sprite {}
}

初始化时,flash 将创建此类的一个实例并将其附加到舞台上。这将类似于 AS2 的概念_root-src传递给的开关mxmlc.exe设置支持这个主类的其余类/包的路径。

因此,你的主类,不管你怎么称呼它,都应该继承自Sprite.

  • 在我成功指定一个主类之后,我可以简单地将我的入口点代码移动到我的主类的构造函数中吗?

是的。您的“主类”的构造函数将是您的 swf 的入口点。

  • “正如我习惯在“真正的”JavaScript 中做的那样,我添加了一个 Function.prototype.bind=function() 函数,这样,当我有回调时,这将被正确设置。这仍然有效吗?我可以添加方法吗到 Function 的原型?”

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);

...都是不同的

  • “我还需要绑定上下文吗?如果我在没有 bind(this) 的情况下调用 positionTimeoutID=setTimeout(fireSoundPosition.bind(this), 1000) 之类的东西,Flash 会将正确的 this 传递给我的回调方法吗?”

这取决于,如果它是一个类方法,那么它总是会被绑定(参见最后一节)。如果闭包/匿名函数,那么是的,它仍然需要绑定到指定this.

  • Flex 编译器抱怨几个 API 方法发生了变化,所以也许修改我的调用改变了一些东西,我不理解新的 API。有没有办法调试这个 SWF?写入浏览器控制台?哔?任何事物?无需从 Adob​​e 购买一些大型 IDE 之类的?

你可能想去获得Flash 调试播放器。并且编译器应该带有fdbFlash 命令行调试器。这个想法是,当您在调试播放器中托管/运行您的应用程序时,您可以附加fdb到实例和trace(),以及设置断点和查看异常。

  • 在我原来的类中,我添加了一个全局函数来使用 Array.from=function(object:Object) 将对象转换为数组。当我处于严格模式时,这给了我一个错误——显然是因为它不喜欢我向 Array 类对象添加静态方法。这仍然可以在非严格模式下工作吗?有什么问题?如果我将它转换为我课堂上的普通方法,它会起作用吗?

我将不得不研究这个,尽管我认为“正确的” AS3 解决方案是从另一个类创建一个静态方法来执行此操作,而不是尝试Array直接扩展。就像是:

package {

    public class ArrayHelpers {
        public static From(object:Object):Array {
            /* do work */
        }
    }

}

然后将其称为:ArrayHelpers.From(whatever);

于 2012-01-18T18:09:30.867 回答
1

感谢 32bitkid 的全面回复。我终于得到了这个工作。只是为了填写剩余问题的答案,以下是我在这漫长的一天实验中的一些经验。

首先,要获得一个主类,您只需在mxmlc命令行中指明该类。该类不必位于根包中。将启动的东西放在类构造函数中。哦,从其他网站看来,该类可能需要扩展Sprite或影片剪辑。

正如 32bitkit 所示,不需要任何绑定内容。但请注意——自 Flash 9 以来,大部分 API 都发生了变化。例如,ExternalInterface.call()现在只需要两个参数,因为您不再需要传递上下文(例如this)。Sound API 已经完全改变。

试图定义Array.from()可能是行不通的。(在扔掉我不再需要的 my 之后Function.prototype.bind(),我不再需要它了。)尝试增加现有的类,例如添加 aString.prototype.endsWith()似乎也不起作用。

但也许我发现的关于调试 SWF 的最重要的事情最终让我找出问题非常重要:去下载调试 ActiveX Flash 播放器并为 IE 安装它。(我只推荐 IE 版本,因为这个练习的重点是我试图让 WAV 文件在 IE 上播放——唯一不支持 WAV 文件的主要浏览器。Grumble grumble。)说真的,调试Flash播放器是无价的。独立调试播放器不支持ExternalInterface.

哦,还有一种帮助调试的简单方法?只需回调浏览器的日志记录例程,如下所示:

ExternalInterface.call("console.info", "Hello, world!");

它就像一个魅力!哦,还有最后一件事:在代码开始时立即打开它,当您从 JavaScript 调用 SWF 时,异常会回来并显示在浏览器的调试器中(反之亦然)!

ExternalInterface.marshallExceptions = true;

当我以为我只需要修改几行代码时,我一整天都被迫升级到 ActionScript3、Flash 10 和 Flex 等。现在我至少已经有了连接,这在很大程度上要感谢这里的反馈,明天我会跳回去尝试找出为什么我不能播放 WAV 文件--- 这就是重点运动开始。

于 2012-01-19T02:43:58.070 回答