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