1

何年も前に、さまざまなブラウザーで MP3 ファイルを再生するためだけに、小さくてシンプルな SWF を作成しました。インターフェイスを公開し、JavaScript から呼び出しました。それはすべて小さくて簡単でした。Guise.asソースコード全体を見ることができます。

を使用してメイン クラスをコンパイルしましたmtasc。これにより、初期化コードのメイン関数を指定できます。

/**Main entry point.*/
static function main(mc)
{

これは、WAV サポートを追加するまでは問題なく機能していました。Flash はネイティブで WAV をサポートしていないので、ライブラリを追加してみました。しかし、ライブラリには Flash 10 が必要で、 ではコンパイルできないためmtasc、Flex 4.6 をダウンロードして使用してみましたmxmlc。男の子、私の痛みは始まったばかりでした。

コンパイル済みの SWF が機能しなくなりました。MP3 ファイルでも機能しません。どこから問題を見つけたらよいかわかりませんが、答えのない質問がたくさんあることはわかっています。おそらく、そのうちの 1 つが私の問題です。

  • 私の理解が正しければmxmlc、「メイン エントリ ポイント」の概念はありませんが、Flash は単純に「メイン クラス」のインスタンスを作成します。しかし、メイン クラスを指定するにはどうすればよいでしょうか。コマンド ラインで を使用してクラスを参照mxmlcすると、そのクラスは自動的にメイン クラスになりますか? それとも、クラスがルート (つまり、ない) パッケージにあることが絶対に必要ですか? 特別な名前が必要ですか?
  • メイン クラスを正常に指定した後、エントリ ポイント コードをメイン クラスのコンストラクタに移動するだけでよいですか?
  • 元のクラスでは、 を使用してオブジェクトを配列に変換するグローバル関数を追加しましたArray.from=function(object:Object)Arrayこれにより、厳密モードにいるときにエラーが発生しました---明らかに、クラスオブジェクトに静的メソッドを追加するのが好きではないためです。これは厳密でないモードでも機能しますか? どうしたの?クラスの通常のメソッドに変換すると、機能しますか?
  • 「実際の」JavaScript で行うことに慣れているFunction.prototype.bind=function()ので、関数を追加して、コールバックがあるときにthis正しく設定されるようにしました。これはまだ機能しますか?のプロトタイプにメソッドを追加できますFunctionか?
  • もうコンテキストをバインドする必要さえありますか? positionTimeoutID=setTimeout(fireSoundPosition.bind(this), 1000)のようなものを なしで呼び出した場合bind(this)、Flashthisはコールバック メソッドに正しいものを渡しますか?
  • Flex コンパイラは、いくつかの API メソッドが変更されたと不平を言ったので、呼び出しを変更すると何かが変更された可能性があり、新しい API を理解できません。この SWF をデバッグする方法はありますか? ブラウザ コンソールに書き込みますか? ビープ音?なんでも?Adobe などから大きな IDE を購入することなく?

フィードバックをいただければ幸いです。ほんの 1 つか 2 つの小さな調整ですべてが台無しになっていることは確かですが、おそらくコミュニティの助けがあれば、SWF を再コンパイルするためだけに本全体を読んだり、新しい SDK を購入したりするのに数日を費やす必要はありません。いくつかの新しい呼び出し...ありがとう。

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 {}
}

初期化時に、フラッシュはこのクラスのインスタンスを作成し、ステージにアタッチします。これは、 の AS2 の概念に似てい_rootます。に渡された-srcスイッチはmxmlc.exe、このメイン クラスをサポートする残りのクラス/パッケージへのパスを設定します。

そのため、メイン クラスは、何と呼んでも、 から継承する必要がありますSprite

  • メイン クラスを正常に指定した後、エントリ ポイント コードをメイン クラスのコンストラクタに移動するだけでよいですか?

はい。「メイン クラス」のコンストラクタは、swf のエントリ ポイントになります。

  • 「私は「実際の」JavaScript で行うことに慣れているので、Function.prototype.bind=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()これら 4 つの関数呼び出しは、常に元の関数にバインドされるため、まったく同じ結果が生成されます。

これはクラスメソッドにのみ適用され、無名関数/クロージャーには適用されないことに注意してください。そう...

var func:Function = function():void { alert(this); }
func();
func.call(cls);
func.call(undefined);

…どれも違う

  • 「もうコンテキストをバインドする必要がありますか? positionTimeoutID=setTimeout(fireSoundPosition.bind(this), 1000) のようなものを bind(this) なしで呼び出すと、Flash は正しい this をコールバック メソッドに渡しますか?」

それがクラスメソッドである場合は、常にバインドされます (最後のセクションを参照)。クロージャー/匿名関数の場合、はい、指定するためにバインドする必要がありますthis

  • Flex コンパイラは、いくつかの API メソッドが変更されたと不平を言ったので、呼び出しを変更すると何かが変更された可能性があり、新しい API を理解できません。この SWF をデバッグする方法はありますか? ブラウザ コンソールに書き込みますか? ビープ音?なんでも?アドビなどから大きな IDE を購入することなく?

おそらく、フラッシュ デバッグ プレーヤーを入手したいと思うでしょう。また、コンパイラにはfdb、フラッシュ コマンドライン デバッガである が付属している必要があります。アイデアは、デバッグ プレーヤーでアプリをホスト/実行するときfdbに、インスタンスにアタッチしたりtrace()、ブレークポイントを設定したり、例外を表示したりできるということです。

  • 元のクラスでは、Array.from=function(object:Object) を使用してオブジェクトを配列に変換するグローバル関数を追加しました。これにより、strict モードのときにエラーが発生しました。これは、明らかに、静的メソッドを 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 に感謝します。私はついにこれを機能させました。残りの質問への回答を記入するために、この長い 1 日の実験での私の経験の一部を以下に示します。

まず、メイン クラスを取得するには、mxmlcコマンド ラインでそのクラスを指定するだけです。クラスはルート パッケージにある必要はありません。起動用のものをクラス コンストラクターに入れます。ああ、他の Web サイトからは、クラスを拡張Spriteまたはムービー クリップする必要があるようです。

32bitkit が示すように、バインドは必要ありません。ただし、Flash 9 以降、多くの API が変更されていることに注意してExternalInterface.call()くださいthis。また、Sound API は完全に変更されました。

定義しようとしても、Array.from()おそらくうまくいきません。(不要になった my を捨てた後Function.prototype.bind()は必要ありませんでした。) a を追加するなど、既存のクラスを拡張しようとしてもString.prototype.endsWith()うまくいかないようです。

しかし、SWF のデバッグに関して、最終的に問題を突き止めることができた最も重要なことは、おそらく非常に重要なことです。デバッグ用の ActiveX Flash プレーヤーをダウンロードして、IE 用にインストールしてください。(この演習の要点は、WAV ファイルをサポートしていない唯一の主要なブラウザーであるIE で再生することです。Grumble grumble.) まじめな話、デバッグ Flash プレーヤーは非常に貴重です。スタンドアロンのデバッグ プレーヤーは をサポートしていませんExternalInterface

ああ、デバッグを助ける簡単な方法はありますか? 次のように、ブラウザのロギング ルーチンにコールバックするだけです。

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

それは魅力のように機能します!最後にもう 1 つ: これをコードの開始時にすぐにオンにすると、JavaScript から SWF を呼び出すと、例外が戻ってきてブラウザーのデバッガーに表示されます (逆の場合も同様です)。

ExternalInterface.marshallExceptions = true;

数行のコードを変更するだけだと思っていたのに、ActionScript3、Flash 10、Flex などに移行することを余儀なくされて 1 日を過ごしました。ここでのフィードバックのおかげで、少なくとも接続が完了したので、明日また戻って、 WAV ファイルを再生できない理由を突き止めようと思います。はじめに運動。

于 2012-01-19T02:43:58.070 に答える