図6●敵のインスタンスを作成して名前を付ける
図6●敵のインスタンスを作成して名前を付ける
[画像のクリックで拡大表示]
図7●ステージ上に配置するインスタンスの名前
図7●ステージ上に配置するインスタンスの名前
[画像のクリックで拡大表示]
リスト4●<b>リスト3</b>に追加する衝突判定用コード
リスト4●<b>リスト3</b>に追加する衝突判定用コード
[画像のクリックで拡大表示]
リスト5●降ってくる敵を避けるゲームのコード
リスト5●降ってくる敵を避けるゲームのコード
[画像のクリックで拡大表示]
リスト3●矢印キーでインスタンス(myship)を上下左右に移動させるコード
リスト3●矢印キーでインスタンス(myship)を上下左右に移動させるコード
[画像のクリックで拡大表示]
図A● hitTestメソッドによる当たり判定。
図A● hitTestメソッドによる当たり判定。
[画像のクリックで拡大表示]

二つのインスタンスの衝突を判定する

 次に,上から降ってくる敵を作成します。ステージに適当に丸の絵を一つ描き,「シンボルに変換」ダイアログボックスを表示し,enemyとシンボル名を付けてムービークリップとして登録します。次に,ステージ上のインスタンスにenemy1とインスタンス名を付けます(図6[拡大表示])。

 インスタンスmyShipと,インスタンスenemy1の二つが衝突しているかどうかを判定するには,MovieClipクラスのhitTestメソッドを使用します。hitTestメソッドは,引数として任意のムービークリップのインスタンスの参照を渡すと,そのインスタンスと衝突している場合にはtrueを,衝突していない場合にはfalseを返します(カコミ記事「hitTestメソッドの当たり判定」を参照)。

 リスト3[拡大表示]の関数routineWork内の末尾に,リスト4[拡大表示]のようにコードを追加し,ムービープレビューで確認をしてみましょう。矢印キーでmyShipを移動し,enemy1と接触をすると,[出力]ウィンドウに「衝突しています!」とメッセージが表示されます。複数のインスタンスとの衝突判定を行うには,forステートメントなどを使用してhitTestメソッドによる判定を繰り返します。

ゲーム画面を構成する

 衝突判定の方法がわかったところで,ゲームらしい画面を作成してみましょう。メニューから[ウィンドウ]-[ライブラリ]とたどって[ライブラリ]パネルを表示させ,そこからenemyを選んでステージ上にドラッグ・アンド・ドロップします。enemyのインスタンスを新たに三つ並べたら,それぞれインスタンス名を「enemy2」「enemy3」「enemy4」とします。

 さらに,[テキストツール]を使ってテキスト・フィールドを一つ配置し,[プロパティ]パネルのドロップダウンリストで「ダイナミックテキスト」を選び,score_txtとインスタンス名を付けます(図7[拡大表示])。ちなみに図7の画面は,メニューで[修正]-[ドキュメント]とたどって表示される[ドキュメントプロパティ]パネルを使って,幅250,高さ400の大きさに調整を行っています。

 これで基本的なゲーム画面は完成しました。後は敵を上から下へと移動させ,myShipと衝突したら,スコアが減るような形にしてみます。最終的なコードは,リスト5[拡大表示]のようになります。

 リスト4との大きな違いは,forループを使って,enemy1~enemy4の四つの敵についてそれぞれ,移動処理と当たり判定を実行しているところです。ここで,連番で名付けられたインスタンスに順番に処理を行う場合にとても便利な方法を使っていますから,説明しておきましょう。

 (1)をご覧ください。これは「[ ](配列アクセス演算子)」を使った構文です。配列アクセス演算子を使うと,文字列から任意のインスタンスの要素(プロパティ,メソッド,変数,インスタンスなど)への参照を取得できます。(1)では,iをカウンタ変数とするforループの中でroot["enemy" + i]への参照,つまり順番にenemy1~enemy4までの参照を取得し,変数tmpEnemyに代入してその後の処理に使っています。

 リスト5のコードを記述し,ムービープレビューで確認してみましょう。上から四つの敵が降ってきて,それに自機が衝突するとスコアが減算されることを確認できます。あとは自機や敵の絵を変更したり,アニメーションを持つムービークリップを作成したり,背景を描いたりすれば,より,ゲームらしくなりますね。前回ご紹介したように,タイトル画面や終了画面を追加しても良いでしょう。

☆     ☆     ☆

 今回は,ここまでです。矢印キーで移動して,落ちてくる敵と衝突判定を行えることは確認できました。次回はこちらから攻撃ができるようにゲームを改良します。さらに,複数種類の敵を動的に数を変更して出現させたり,衝突したら爆発する絵や音を出すようにしてゲームとしての完成度を高めます。

 なお今回のコードは,メインのタイムライン上の関数routineWork内で集中して移動処理や衝突判定の処理を行いました。自機のスピードや,敵の数や出現位置などを管理する変数(定数)も,メインのタイムライン上の要素として管理しています。こうした記述スタイルは,コードの記述が1カ所に集中します。そのため,今回のように短いコードであればとても見通しが良く,管理しやすくなります。

 このほかに,シンボルをクラスに見立て,各シンボルごとにプロパティ,メソッドを実装して管理するオブジェクト指向プログラミングのスタイルでコードを記述することも可能です。ActionScript2.0では,独立したクラス・ファイルを作成し,シンボルと関連付けて使用することができます。こちらの記述スタイルに関しては,次回,詳しく紹介します。

hitTestメソッドの当たり判定

 インスタンス同士の衝突を,hitTestメソッドを使って判定する場合,その「当たり判定」は,各々のインスタンスを囲む四角形同士が重なっているかどうかで判定されます(図A[拡大表示])。そのため,インスタンスの形によっては,見た目では衝突していないように見えるのに,hitTestメソッドの結果は衝突をしているtrueを返すことがあります。

 この現象を回避するには,当たり判定用の小さなインスタンスを別に作成し,そのインスタンスを自機のインスタンスと一緒に移動させながらhitTestメソッドを使用したり,インスタンスそのものの形を四角に近いものに変更したりといった方法が簡単です。そのほか,インスタンス同士ではなく,座標単位でhitTestメソッドを使用する方法も用意されています*A

下記のURLから、サンプル・プログラムを無償ダウンロードできます。
http://software.nikkeibp.co.jp/software/download/down04c.html#200412