まずはActionScriptの実行順番を把握する。
ActionScriptは深度の上から順番に実行される。
MovieClipのアクションは表示される深度の下から実行される。
下記のようなタイムラインの場合
|深度|フレーム|名前|
| 7 | a | [as1] |
| 6 | ● | [MC1] |
| 5 | a | [as2] |
| 4 | a | [as3] |
| 3 | ● | [MC3] |
| 2 | ● | [MC2] |
| 1 | a | [as4] |
次のように実行される
as1
as2
as3
as4
MC2のアクション
=> MC2内のMovieClipのアクション
MC3のアクション
=> MC3内のMovieClipのアクション
MC1のアクション
=> MC1内のMovieClipのアクション
MovieClipの中のアクションも同じように実行されていく。
はまったところ
MC2でMC1のフレームを移動してもMC1の移動する前のアクションは実行される。
MC2のアクション
trace("mc2");
MC1.gotoAndPlay(2);
MC1のフレームとアクション
フレーム1のアクション
stop();
trace("frame1");
フレーム2のアクション
trace("frame2");
とした場合
mc2;
frame1;
frame2;
frame1;
と出力される。
JavaScriptだと
まずはフレームのアクションを実行して
深度の低いMovieClipのアクションを実行。
この際にフレーム移動先でアクションがある場合は
その度に別の配列に格納しておいて最初のアクションの実行が完了したら
次は配列に格納されたアクションを実行する
これを繰り返す事で動いた。
MovieClip.prototype.addActions = function()
{
var _this = this;
// メインのアクション
if (_this.isAction) {
var frame = _this.getFrame();
var as = _this.getActions(frame);
if (as != undefined) {
var player = _this.player;
var actions = player.actions;
var queue = player.queue;
var obj = { as: as, mc: _this };
if (queue == null) {
actions[actions.length] = obj;
} else {
queue[queue.length] = obj;
}
}
_this.isAction = false;
}
// 深度の若い順番にアクションを実行
var tags = _this.getTags();
var _addActions = _this.addActions;
var _btnCallback = _this.btnCallback;
var length = tags.length;
for (var depth = 1; depth < length; depth++) {
if (!(depth in tags)) {
continue;
}
var tag = tags[depth];
// loadMovieでよばれた別swfは形式を合わせる
if (tag instanceof Player)
tag = tag.getParent();
if (tag instanceof MovieClip) {
_addActions.call(tag);
} else if (tag.characters instanceof Array) {
// ボタンの状態でアクションを実行
_btnCallback.call(_this, tag, _addActions);
}
}
};
後は、queueにデータがあればひたすら実行
while(actions.length) {
queue = [];
// アクションを実行
for (var i = 0; i < actions.length; i++) {
action[i].execute();
}
actions = queue;
}
よしよし。
これで問題ないはず。
と思ったが、フレーム移動があった場合のアクションの順番は
このルールに当てはまらないorz
フレーム移動の際のアクションの順番
レンダリング後、フレーム移動して移動先にアクションがある場合
(新規のMovieClipやフレーム終了したMovieClipは先の条件で呼ばれる)
最後にレンダリングされたMovieClipのアクションから実行される。
root
|a|a|
|●|●|MC2
|●|●|MC1
MC1
|a|a|
MC2
|a|a|
とした場合
1フレーム
root_frame1
mc1_frame_1
mc2_frame_1
ここは最初のルールが適用
2フレーム
mc2_frame_2
mc1_frame_2
root_frame2
2回目の1フレーム
mc2_frame_1
mc1_frame_1
root_frame1
2回目の2フレーム
mc2_frame_2
mc1_frame_2
root_frame2
ルールは二つ
- 初回アクション実行時とアクションでフレーム移動があった場合
- レンダリング後、フレーム移動した場合
こんどこそできたorz
完成品
ベースはこれでできたので、次はSWF5,SWF6で使う
onClipEventを調べてみよう。