マニュアル:BulletHell(弾幕)サンプルプロジェクト

このチュートリアルでは、弾幕システムのサンプルゲーム BulletHellSample の全体構造と実装メカニズムについて解説します。


◆ ゲーム概要

これは、射撃爆弾 を使って、HP 500 で弾幕を放つボスを倒すゲームです。
これはサンプルプロジェクトのため、ボスを倒すとゲームは終了します。

操作方法

  • 方向キー:移動
  • Z キー:射撃
  • X キー:爆弾

弾幕ゲームでよく見られるメカニズム、例えば グレイズ(擦弾)爆弾による弾消し を実装しています。


ゲームシーン構造

ゲームは1つのシーンのみを使用します:test_scene.tscn
シーン切り替えはありません。


オブジェクト構造

プレイヤー

player.tscn はプレイヤーキャラクターのシーンです。

その子ノードには以下が含まれます:

  • GrazeObject.tscn:グレイズ判定用
  • player_hit_checker.tscn:被弾判定用

enemy.tscn は敵(ボス)のシーンです。

その子ノードには以下が含まれます:

  • damage_checker.tscn:被弾判定用

各機能の実装説明

敵の弾幕

敵は「一定時間間隔で弾幕を発射する」というシンプルな実装方式を採用しています。

弾幕の内容は以下の通りです:

  1. 加速する全方位弾
  2. 移動と連動したショットガン式弾幕
  3. レベルの端から発射され、プレイヤーを狙う分裂弾
  4. 全方位弾を組み合わせた花形弾幕
  5. 方向転換弾で描くシンプルな幾何学図形

弾幕には繰り返し音声を再生する必要があるため、AnimationPlayer ノード を使って AudioStreamPlayer で音を再生しています。

現在、適切な音声リソースが不足しているため、このような実装になっています。
理想的には、各弾幕ごとに適切な音声を用意し、発射時に直接再生すべきです。

  • 現在の弾幕システムには 停止機構がありません。そのため、敵が倒されても、すでに生成された弾幕は引き続き発射されます。
    この問題は今後のアップデートで弾幕停止機能を追加することで解決予定です。
    現時点では、繰り返し処理を使わず、状態を分割して手動でループロジックを実装する ことで回避できます。

プレイヤーの通常射撃弾幕

プレイヤーは 1つの状態で同時に4種類の弾幕を発射 します。

現在、連射タイプの弾幕では直接発射方向を指定できません。
そのため、非常に遠いグローバル座標に向けて発射する ことで、方向射撃の効果を模倣しています。

  • 今後のアップデートで、直接方向を指定して発射できるようにする予定です。

グレイズ処理

GrazeObject.tscn をプレイヤーの子ノードとして配置することでグレイズ機能を実現しています。

このオブジェクトは、プレイヤーの被弾判定よりも広い衝突範囲 を持っています。
敵弾と接触した場合:

  • グレイズのパーティクルエフェクトを再生
  • スコアを増加

被弾処理

プレイヤーと敵の被弾処理は、独立した子オブジェクト を通じて実装されています。

主な理由は2つ:

  1. 被弾によって現在実行中の状態が中断されることを避けるため
  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:加算する数値