このチュートリアルでは、弾幕システムのサンプルゲーム BulletHellSample の全体構造と実装メカニズムについて解説します。
◆ ゲーム概要
これは、射撃 と 爆弾 を使って、HP 500 で弾幕を放つボスを倒すゲームです。
これはサンプルプロジェクトのため、ボスを倒すとゲームは終了します。
操作方法
- 方向キー:移動
- Z キー:射撃
- X キー:爆弾
弾幕ゲームでよく見られるメカニズム、例えば グレイズ(擦弾) や 爆弾による弾消し を実装しています。
ゲームシーン構造
ゲームは1つのシーンのみを使用します:test_scene.tscn。
シーン切り替えはありません。
オブジェクト構造
プレイヤー
player.tscn はプレイヤーキャラクターのシーンです。
その子ノードには以下が含まれます:
GrazeObject.tscn:グレイズ判定用player_hit_checker.tscn:被弾判定用
敵
enemy.tscn は敵(ボス)のシーンです。
その子ノードには以下が含まれます:
damage_checker.tscn:被弾判定用
各機能の実装説明
敵の弾幕
敵は「一定時間間隔で弾幕を発射する」というシンプルな実装方式を採用しています。
弾幕の内容は以下の通りです:
- 加速する全方位弾
- 移動と連動したショットガン式弾幕
- レベルの端から発射され、プレイヤーを狙う分裂弾
- 全方位弾を組み合わせた花形弾幕
- 方向転換弾で描くシンプルな幾何学図形
弾幕には繰り返し音声を再生する必要があるため、AnimationPlayer ノード を使って AudioStreamPlayer で音を再生しています。
現在、適切な音声リソースが不足しているため、このような実装になっています。
理想的には、各弾幕ごとに適切な音声を用意し、発射時に直接再生すべきです。
- 現在の弾幕システムには 停止機構がありません。そのため、敵が倒されても、すでに生成された弾幕は引き続き発射されます。
この問題は今後のアップデートで弾幕停止機能を追加することで解決予定です。
現時点では、繰り返し処理を使わず、状態を分割して手動でループロジックを実装する ことで回避できます。
プレイヤーの通常射撃弾幕
プレイヤーは 1つの状態で同時に4種類の弾幕を発射 します。
現在、連射タイプの弾幕では直接発射方向を指定できません。
そのため、非常に遠いグローバル座標に向けて発射する ことで、方向射撃の効果を模倣しています。
- 今後のアップデートで、直接方向を指定して発射できるようにする予定です。
グレイズ処理
GrazeObject.tscn をプレイヤーの子ノードとして配置することでグレイズ機能を実現しています。
このオブジェクトは、プレイヤーの被弾判定よりも広い衝突範囲 を持っています。
敵弾と接触した場合:
- グレイズのパーティクルエフェクトを再生
- スコアを増加
被弾処理
プレイヤーと敵の被弾処理は、独立した子オブジェクト を通じて実装されています。
主な理由は2つ:
- 被弾によって現在実行中の状態が中断されることを避けるため
- グレイズ判定 と 被弾判定 を明確に区別するため
- ACTION GAME MAKER では、HitArea2D がルートノード以下のすべての HitArea の衝突を検出するため、子ノードの判定も拾ってしまいます。
この問題は「子ノードではなく、子オブジェクトとして生成する」ことで回避できますが、判定位置を視覚的に確認しやすくするため、本サンプルでは子ノード方式を採用しています。
弾幕のレイヤー構造
レイヤー設定は以下の通りです:
- プレイヤー:Layer 1
- 敵:Layer 2
- グレイズ判定:Layer 3
弾幕のレイヤー:
- 敵弾幕:Layer 1、3
- プレイヤー弾幕:Layer 2
爆弾の実装
爆弾は弾幕システムの一部ではなく、通常の弾丸 として実装されています。
bomb.tscn は爆弾のシーンです。
機能は以下の通り:
-
画面全体をカバーする衝突判定を設定
-
命中した弾幕を消去
-
10% の確率 で消去された弾幕をスコアアイテムに変換
-
同時に敵本体にダメージを与える
-
スコアアイテムへの変換には オブジェクト生成 が関与するため、比較的重い処理です。
変換確率を100%にするとパフォーマンスが低下します。
この問題の最適化案は別途検討中です。
スコアアイテム
オブジェクト生成によるパフォーマンス負荷を軽減するため、スコアアイテムは GDScript で実装されています。
- シーン:
score_test.tscn - 動作:
- プレイヤーに近づく
- 十分に近づいたら消滅
- 指定された変数値を増減
Score ノードの Inspector で以下のパラメータをカスタマイズできます:
- PickUpRadius:拾取判定距離
- PullSpeed:移動速度
- Group:近づく対象グループ
- Project Variable:変更するプロジェクト変数名
- Variable Add:加算する数値