Flashのステージ(親swf)に外部のswf(子swf)をロードして、子swfから親swfの関数にアクセスしようとしてハマりました。
以下、うまく動作したソースです。
親のタイムライン上のbtn_1を押したとき、親のタイムライン上にLoaderを直接置いて、そこに子を呼び出して、子の中のボタンが押されたときに親のタイムラインの関数invisibleを呼んでいます。
親swfのメインタイムライン
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var url1:URLRequest = new URLRequest("page1.swf"); // ローダーオブジェクトを作成し配置 var loader_obj:Loader = new Loader(); this.addChild (loader_obj); // 見えなくする function invisible():void { loader_obj.visible = false; } btn_1.addEventListener(MouseEvent.CLICK, click_1, false, 0, true); function click_1(event:MouseEvent):void { loader_obj.visible = true; loader_obj.load(url1); } |
子swfの中のムービークリップのボタンのタイムライン
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
this.stop(); this.buttonMode = true; this.addEventListener(MouseEvent.MOUSE_OVER, over, false, 0, true); this.addEventListener(MouseEvent.MOUSE_OUT, out, false, 0, true); this.addEventListener(MouseEvent.CLICK, click, false, 0, true); function over(event:MouseEvent):void { this.gotoAndStop(3); } function out(event:MouseEvent):void { this.gotoAndStop(2); } function click(event:MouseEvent):void { MovieClip(Loader(root.parent).root).invisible(); } |
まず、子swfにMovieClip(root)と書いても親を指しません。子単体で動かしたときと同じで、子のメインタイムラインを指します(正確にはちょっと違いますがイメージとして)。
そして、Loaderは呼び出しの際には箱を生成してそこにswfを展開するので、Loader自体を子から指すにはroot.parentとする必要があります。
また、親からすれば子はLoaderの中のものなのでMovieClipではなくLoaderにキャストする必要があります。なので、Loader(root.parent)となり、これで親で設置したLoaderのところまできました。
そのLoaderのrootがメインタイムラインとなるので、MovieClip(Loader(root.parent).root)として、後ろに関数をつければ完成です。
え!?
もう一つ、ポイントがあります。
rootのstageは特別なので(確か)、そこに設置したら手が出せなくなります。そしてStageは静的なのでキャストできないんです(多分)。
実は最初、親swfでthisではなく、stageにaddChildしてしまっていたんです(ブログからコピペして)。大ハマリしましたので頭の片隅にでもちょろっと置いておいてください。