2

AS3 コンテナーから AS2 関数を呼び出すという質問に答えようとしているときに、障害に遭遇しました。セットアップは、AS2 SWF をロードする AS3 SWF であり、AS2 SWF は別の AS2 SWF をロードします。AS3 SWF と親 AS2 SWF 間の通信は、localConnection を介して行われます。

child_as2.swf - フレーム 1 に次のコードを含む、ボックスが画面上を移動する非常に単純なタイムライン アニメーションです。

stop();
function playMovie() {
    play();
}

parent_as2.swf - これは、child_as2.swf に読み込まれる中間 AS2 コンテナーです。ロードは LocalConnection 呼び出しによってトリガーされます。

import mx.utils.Delegate;

this._lockroot = true;

var container:MovieClip = createEmptyMovieClip("container", 10);
//mustn't cast this or the Delegate breaks
var mcLoader = new MovieClipLoader();
mcLoader._lockroot = true;
mcLoader.onLoadInit = Delegate.create(this,onMCLoadInit);

function onMCLoadInit() {
    trace("load init");
    container.playMovie();
}

//LocalConnection code
var myLC:LocalConnection = new LocalConnection();

myLC.loadChild = function(){
    mcLoader.loadClip("child_as2.swf", container);
    trace("loading");
}

myLC.connect("AVM");

parent_as3.swf - AS3 で記述された外側のラッパーです。parent_as2.swf をロードし、LocalConnection を介して通信します。

var myLC:LocalConnection = new LocalConnection();

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT,onLoaded);
loader.load(new URLRequest("parent_as2.swf"));
addChild(loader);


function onLoaded(event:Event):void {
    //setTimeout hack to circumvent #2000 Security context error
    setTimeout(function() {
        myLC.send("AVM", "loadChild");
    },1);
}

問題はonMCLoadInit、parent_as2 の関数が AS3 ラッパー内にロードされたときに呼び出されないことです。ただし、ロードは行われます。Delegate の代わりにリスナー オブジェクトを使用すると、イベントも失敗します。child_as2.swf のボックスは表示されますが、動きません。ただし、parent_as2.swf を単独で実行し、LocalConnection なしでロードを開始すると、正常に動作します。また、外部の LocalConnection 呼び出しからトリガーされた場合にも正しく機能します。AS3 ラッパーが MovieClipLoader のイベントの発生を妨げるのはなぜですか?

アップデート:

MovieClipLoader.getProgress()したがって、parent_as2.swf の MovieClipLoader からイベントを起動できないことを受け入れて、ポーリングと child_as2.swf の関数の存在を組み合わせて loadInit 状態を検出するようにコードを変更しました。きれいではありませんが、うまくいくようです。ただし、イベントを使用してソリューションを提供できる方がはるかに望ましいです。

var container:MovieClip = createEmptyMovieClip("container", 10);
var mcLoader:MovieClipLoader = new MovieClipLoader();
var loadStarted:Boolean;
var checkingInt:Number;

function checkProgress() {
    var progObj:Object = mcLoader.getProgress(container);
    if(progObj.bytesLoaded == progObj.bytesTotal && loadStarted) {
        //load complete, wait for loadInit
        if(typeof(container.playMovie) == "function") {
            //loadInit
            clearInterval(checkingInt);
            container.playMovie();
        }
    }
    //ensures the first loop is ignored due to inaccuracy with reporting
    loadStarted = true;
}

//LocalConnection code
var myLC:LocalConnection = new LocalConnection();

myLC.loadChild = function() {
    loadStarted = false;
    mcLoader.loadClip("child_as2.swf", container);
    checkingInt = setInterval(checkProgress,5);
}

myLC.connect("AVM");
4

1 に答える 1

0

親にロードすると、親が_rootになるas2のデリゲートスコープだと思います。
したがって、「これ」は、関数が存在しない親ル​​ートを参照します。parent_as2
を入れてみましたか?this._lockroot = true;

これがより良い説明です

また、セキュリティハックの補足として。
そのための適切な修正は、子が親に連絡し、親から子への通信イベントを開始する「I am ready type コマンド」を発行することです。
setTimeout は、子への呼び出しを遅らせて初期化する時間を与えるだけで、低速のコンピューターでは問題になる可能性があります。
私は数年前に AS2 を AS3 にロードすることをたくさんしました。言えないなら笑

于 2011-11-09T20:37:24.337 に答える