gotoAndPlayの謎(2)
(Flash Liteを知っている人向け,…というか単なるメモです)
id:sunflat:20060927 の続き.外部のムービークリップから,tellTarget() { gotoAndPlay() }で再生ヘッドをジャンプさせると,ムービークリップ内部のフレームアクションと干渉して誤動作する問題に関して.
どうやらFlashでは,全ムービークリップの現在位置のフレームアクションが一旦実行予約された後,後から一気に実行される仕組みになっているようだ(推測).
一方で,gotoAndPlay()系の関数は,対象となるムービークリップの再生ヘッド位置(_currentframe)を即変更しまう.
例えば,前回の現象は,mc1がframe 12にいる場合に,他のMovieClipのアクション「 tellTarget(”/mc1”) { gotoAndPlay(10); }」と,mc1のアクション「prevFrame(); play();」が実行予約された後,一気に実行されるために発生する.
これを回避するためには,(他のMovieClipからの)gotoAndPlay()を,即実行するのではなく,実行予約(実行予約系列の末尾に追加)して,今予約されている全アクションを実行した後にgotoAndPlay()を実行してもらえば良さそう.
例えば上の例の場合は,mc1のアクション「prevFrame(); play();」の実行後に,「 tellTarget(”/mc1”) { gotoAndPlay(10); }」が実行されれば問題無い.
解決案
どうすれば,任意のアクションを実行予約系列の末尾に追加できるんだろうか.
とりあえず,新たなムービークリップのインスタンスを生成して,そのムービークリップのフレームアクションの中に,追加したいアクションを書いておけば良い気がする.
シーンのルートに,「jmp」というフレームラベルで,以下のようなサブルーチンを定義
jmpc=(jmpc+1)%1024; duplicateMovieClip("jmp", "jmp" add jmpc, jmpc+30000) tellTarget( "jmp" add jmpc) { t=/:jmpt; l=/:jmpl; }
シーンのルートに,jmpというインスタンス名で空のムービークリップを作成し,先頭フレームに以下のフレームアクションを記述
/:jmpn=_name; if (/:jmpn ne 'jmp') { /:jmpl=l; trace(/:jmpn add ":" add t add " to " add l); // 再生ヘッドを移動させる tellTarget(t) { gotoAndPlay(/:jmpl); } // 自分を消す tellTarget("/") { removeMovieClip(jmpn); } }else{ // prototype役 _visible=false; }
実際にgotoAndPlay()を実行したい時は,以下のようにする.
// tellTarget("targetMovieClip") { gotoAndPlay(label); } の代わり /:jmpt=targetMovieClip._target; /:jmpl=label; tellTarget("/") { call("jmp"); }
もっとマシな解決策がありそうな気がするが,一応望みどおり動いているみたい.