ムービークリップの複製_Flash
ムービークリップの複製
Flashゲームではよく使われるんでないかと思われる、ムービークリップの複製です。これは、たとえば32x32ピクセルのブロックを敷き詰める場合に利用できます。また、敵キャラクタを配置する場合にも利用することができそうです。
まずシンボルをトップメニューの[挿入]-[新規シンボル]にて作成します。アニメーションをしないキャラクタなら「グラフィック」を、アニメーションをするキャラクタなら「ムービークリップ」で作成します。
なお、「敷き詰める」みたいな処理を行いたい場合は編集時にグリッドを表示するようにして座標をきっちりあわせるようにします。トップメニューの[表示]-[グリッド]-[グリッドの編集]にてグリッド間隔をしていして、[表示]-[グリッド]-[グリッドの表示]をチェックするとグリッドが表示されます。上の画像では16x16ごとにグリッドを表示するようにして、32x32のブロックを描いています。これを「block」というシンボル名をつけて、これをActionScriptにて敷き詰めることにします。
次に「ライブラリ」ウィンドウにて対象となるシンボルを選択して、右クリックのポップアップメニューより「リンケージ」を選択します。
「リンケージプロパティ」ウィンドウにて、「ActionScriptに書き出し」のチェックボックスをチェックします。そして、「識別子」にてActionScriptでの認識名称(ここでは「block」としています)を入力して「OK」ボタンを押します。
これで、ActionScript上では「block」という名称でこのシンボルが利用できることになります。
これ以降はActionScript上での処理になります。ルートのドキュメントに肝心の「block」のシンボルを配置していませんが、問題ありません。これをActionScriptにて配置することになります。ので、配置する位置・拡大率・透明度なども全部プログラム的に設定することができます。
ActionScriptでの記述
シンボルを配置するのは「attachMovie」関数でオブジェクトとして生成し、使い終わった後に「removeMovieClip」関数にて破棄します。
attachMovie
obj = _root.attachMovie("block", "block01", 1); obj._x = 30; obj._y = 50;
これでシンボル「block」を「block01」という名称で配置します。「attachMovie」関数の第一引数はシンボルの識別子名、第二引数は他とかぶらないユニークな(ActionScript内での)名称、第三引数は重ね合わせの番号(これも他とかぶってはいけません)になります。重ね合わせの番号は「奥行き」をあらわすもので、1が一番奥になります。その上に重ねる場合は2、3、4...みたいに番号を振っていきます。これは番号がかぶってはいけません。
そして「obj」というオブジェクトが生成されます。これの「オブジェクトのプロパティ」として(_x, _y)にて表示位置をピクセル単位で指定します。「_visible」での表示・非表示はデフォルトでtrueになっています(表示モードです)。
それでは、8 x 8の計64個分を敷き詰めてみます。
objA = new Array(8 * 8); i = 0; sy = 0; for(y = 0; y < 8; y++) { sx = 0; for(x = 0; x < 8; x++) { str = "block" + String(i); objA[i] = _root.attachMovie("block", str, i + 1); objA[i]._x = sx; objA[i]._y = sy; i++; sx += 32; } sy += 32; }
objAを8x8個分の配列として、ここに表示するオブジェクトを順に割り当てていきます。objA[i]に「attachMovie」関数にて作成したオブジェクトを入れています。「block1」「block2」「block3」のような名称で指定して奥行きが1、2、3..となっているのが分かりますでしょうか。そして、座標位置も指定してます。
これを実行すると、
のように敷き詰められることになります。
removeMovieClip
使い終わったムービークリップを破棄します。これは「removeMovieClip」関数にて行います。以下ではムービークリップの破棄の後に配列である「objA」自身を破棄しています。
for(i = 0; i < 8 * 8; i++) { objA[i].removeMovieClip(); } delete objA; objA = null;
タイムラインでの構成
上記の「attachMovie」「removeMovieClip」にてムービークリップまたはグラフィックを制御できますが、タイムライン上では以下のようにするといいかと思います。
第一フレーム目
ここですべての初期化処理を行います。attachMovieもここで行います。
objA = new Array(8 * 8); objA[0] = _root.attachMovie("block", "block01", 1); ...
第二フレーム目
移動処理などを行います。
objA[i]._x = 20; objA[i]._y = 125; ...
第三フレーム目
第二フレーム(イベントループの先頭になるフレーム位置)に戻ります。
gotoAndPlay(2);
このようにすると、1-2-3-2-3-2-3...のようにループが行われて、初期化処理である1フレーム目ははじめの1回しか通らない、とできます(実際のゲームではオープニング画面があり、ゲーム画面、ゲームオーバー画面、ゲームクリア、エンディング、などがありますのでこんなに簡単ではないですが、基本はフレームごとに範囲を決めてフラグを持たせて「今のイベントは何か」というのを判断・ジャンプすることになると思います)。
奥行きを入れ替える
2つのムービークリップのオブジェクトがあるとした場合、これの前後関係を入れ替えます。「swapDepths」関数を使用します。
objA = _root.attachMovie("block", "block1", 1); objB = _root.attachMovie("block", "block2", 2); objA.swapDepths(2);
この場合「objA→objB」のように重ね合わせていたのを「objB→objA」となるように入れ替えられます。「swapDepths」の第一引数は奥行きの入れ替え対象となる奥行き値(Z値)です。なお、オブジェクト自身は入れ替わらずに奥行きのみ入れ替わる点に注意してください。
レイヤーとの前後関係
上記では「_root.attachMovie」としてルート(ドキュメント)に対してムービークリップを追加しました。この場合は、どのようにレイヤーを前後させようとも「常にattachMovieでの描画が手前」になってしまいます。
これを解決するには「_root」ではなく、独自のシンボルを作成してその上にattachMovieするといいです。
たとえば、rootドキュメントに「dodai」というインスタンス名をつけたムービークリップを配置します。この上にattachMovieします。
i = 0; sy = 0; for(y = 0; y < 8; y++) { sx = 0; for(x = 0; x < 8; x++) { str = "block" + String(i); objA[i] = dodai.attachMovie("block", str, i + 1); objA[i]._x = sx; objA[i]._y = sy; i++; sx += 32; } sy += 32; }
「dodai.attachMovie」とすることで、ムービークリップである「dodai」の上に「block」の識別子で示されるムービークリップが配置されます。レイヤーの順番としては「土台(dodaiのムービークリップがある)」「上に重なる」「アクション」としてますので、結果として以下のようになります。
なお、クリッピングする場合は自前で行うようにしてください(マスクするなり、ActionScriptで表示時にクリッピングを行うなり)。
Future's Laboratory 技術格納庫 2004-2013 Yutaka Yoshisaka.