縦スクロールシューティング16

イベントグループ「Bullet」

イベントグループ「shot」で新規に作成した「弾」というアクティブオブジェクト(スプライト)には新規作成と同時に各可変変数には初期値を代入してあるので、新規作成の後には変数に設定された値を参照したり条件比較したりしながら動かしていきます。その「動作全般」を実際に行っているのが「bullet」というイベントグループの役割です。

イベントグループ「Bullet」では変数に代入された設定どおりにスプライトを動かしたり他スプライトに衝突したときの処理を一括して行っているのですが、ここでなるべく一括した処理を行うために各スプライトには「オブジェクトグループ」を適用してあります。発射される弾は複数種類があるのですが変数はちゃんと計画して共通仕様を設けておきます。例えば筆者のよく使う定形だと変数A~Dには「xpos」「ypos」「xmove」「ymove」として、変数Eからは「与ダメージ」とかようやく弾っぽい設定用の変数が続きます。変数の共通仕様は一度決定したらあとから変更するのはやっかいなのでなるべく慎重に計画的に役割とか決めた方が良いです。ちなみに変数名を変えた時だけは自動で各イベントやアクションも変数名が変更されるので変数名を変えるのは楽。しかし一度決めた変数の順番や役割を入れ替えるのは簡単なことではないから注意してください。変数名でイベント行やアクションを検索できないから、もちろん置換もできません。

サンプルの内部ドキュメントには変数一覧が入ってます

サンプルの内部ドキュメントには変数一覧が入ってます

イベントグループ「Bullet」では敵が発射した敵の弾の処理は行っていません。ここで行うのはプレイヤーの発射した弾の管理のみです。オブジェクトグループも敵の撃つ弾とプレイヤーが撃つ弾で別々のオブジェクトグループに属しています。

オブジェクトグループ各種

オブジェクトグループ各種

プレイヤーの弾の挙動にだけは高速ループを使っています。前々回の「Shot」の解説でも触れましたが、プレイヤーの発射した弾に関しては最小の移動単位に近い値で正確にコリジョンを測り当たり判定を取っています。これは「嘘避け」と呼ばれるいい加減な当たり判定を避けるためです。敵の発射する弾には高速ループ使わないのは1つは処理負担を軽くするため、2つ目はゲームとして成立する程度の難易度を保つためには敵が撃つ弾はむちゃくちゃ正確に当たり判定取らなくても良いという考えに基づいてます。つまりゲームが破綻しない程度の嘘避けを敵側の発射する弾には意図的に発生させているってことです。

弾の挙動はプレイヤーの撃つ弾は動作サンプルでは二種類あって、今回その二種類とも基本的に指定された値に沿って一直線に飛んでいくだけなので処理としては変数xmovかymovに定義された移動量を位置情報に加算して実際移動させるのみ、すごく簡単な処理になっています。

高速ループ部分

高速ループ部分

破壊される予定の敵や弾などのスプライトを当たり判定取ってすぐその場で破壊せずに、一旦表示領域画面外に追い出してから破壊する処理はJavaビルドの時に得た経験上のものです。これをやらないとJavaビルドではその場で破壊したはずのスプライトの一部が描画のゴミとしてその場に残るバグが頻繁に確認されました。だからその場ですぐ破壊せずに画面外に追い出してから破壊すれば描画のゴミが出ないねって具合です。SWFや他ビルドでもこういうバグがあるかは分からないのですが、大して重い処理ではないのでこうやって一手間かけてから破壊すればトラブルを避けられるならその方が良いんじゃないかと思い最近は破壊する前に対象オブジェクトを表示画面外に移動させる処理をビルド種類を問わずに必ず行うようにしてます。

スプライトを表示画面外に移動させてから破壊

スプライトを表示画面外に移動させてから破壊

あとは基本的なことなのですが弾とか敵とか、とにかくスプライトを大量に新規作成したら、そのスプライトは破壊を指令するかプロパティオプションから設定を「オン」にしない限り永久に自動では破壊されることは無いので注意してください。

スプライトの自動破壊オプション

スプライトの自動破壊オプション

スプライトの自動破壊オプションはアクティブオブジェクトのプロパティにあります。「距離が離れすぎている」という条件で自動的にスプライトを破壊してくれる便利オプションですが、肝心のこの「距離」について、具体的な数値が明記されていないためもちろん「距離を調整」することも叶わず、このオプションを信じて有効にしたままにすると実は甚だ迷惑な場合もあります。筆者はMMF2にまだ慣れてない頃、このオプションには散々苦しめられたのでこのオプションだけは必ずオフにして使っています。なんでこのオプションを憎むかというと、どの程度の距離で破壊されるか分からんからオブジェクトを通し番号やあるいはXLuaでインポートして管理している場合に非常に不都合があったからです。特にXLuaはオブジェクトを指定IDで管理してるから勝手に破壊されたらその時点でエラーを吐くのです。しかし初心者はプロパティオプションのそんな細かいところまで知らないから、オブジェクトが破壊された理由がまず分からなかったのです。・・・というわけで「自動破壊オプション」は確かに便利なんだけど、「距離」についての定義を開発者側で自由に定義できない以上あまり頼らないほうが良いオプションだと思っています。その代わり開発者は自分で新規作成したオブジェクトは責任を持って自分で後片付けする必要があるし、その必要があることを強く意識した方が良いと思います。例えばサンプルでは特定の領域を超えたらそのスプライトを破壊するというイベントを自分で定義してあります。 

・・というわけでアクティブオブジェクトの自動破壊オプションには注意を払いつつ

  1. デバッガなどを見ながら常にスプライトの数は確認すること
  2. プロパティにはスプライトの数に上限があることを確認する項目もある
  3. スプライトを新規作成したら必ず、次に破壊する時と場所をちゃんと考えること

以上三つは最低限覚えておくと、開発時に余計なイライラを削減できます。

デバッガを開いて確認(左上のオブジェクト数に注意)

デバッガを開いて確認(左上のオブジェクト数に注意)


オブジェクトの上限(各フレームごとの設定)

オブジェクトの上限(各フレームごとの設定)


特定座標にきたら破壊するように指定

特定座標にきたら破壊するように指定