C言語入門|STEP20:ラスボス戦とエンディング処理-特別イベントの実装ポイント

はじめに:物語を終わらせる責任のある処理

STEP19までで、
マップ探索・戦闘・成長・セーブといった
RPGに必要な機能はすべて揃いました。

STEP20では、いよいよ

  • ラスボス「マスタードラゴン」との戦闘
  • 通常戦とは異なる特別な扱い。
  • 勝利後のエンディング演出

を実装している部分を読み解きます。

ゲームをどう終わらせるか は、
実はとても大切な設計ポイントです。

ラスボス専用マスの判定

ラスボス戦は、
マップ上の特定のマスで発生します。

else if (cell == 'B') {
    ...
}

この判定の意味

記号役割
Bラスボス専用マス
E通常の敵
T宝箱
I宿
C教会

通常の敵と分けることで、
特別な処理を簡単に書ける ようになります。

ラスボスの初期化処理

ラスボスは、
ランダム生成ではなく、固定の能力で生成されます。

Enemy boss;
memset(&boss, 0, sizeof(boss));

snprintf(boss.name, sizeof(boss.name), "マスタードラゴン");

boss.max_hp = 220; boss.hp = 220;
boss.max_mp = 35;  boss.mp = 35;

boss.atk = 18;
boss.magic = 14;

boss.exp = 0;
boss.is_boss = 1;

通常の敵との違い

項目通常敵ラスボス
生成方法ランダム固定
HP低〜中非常に高い
is_boss01
EXPありなし

ボス戦は、
成長の結果を試す場 なので、
経験値は不要という設計です。

ラスボス専用の魔法設定

ラスボスには、
専用の強力な魔法が設定されています。

boss.spells[0] = (EnemySpell){ "ドラゴンブレス", EN_SPELL_DMG, 8, 3 };
boss.spells[1] = (EnemySpell){ "深紅の再生", EN_SPELL_HEAL, 10, 28 };
boss.spells[2] = (EnemySpell){ "覇王の咆哮", EN_SPELL_ATKUP, 8, 3 };
boss.spells[3] = (EnemySpell){ "鱗の要塞", EN_SPELL_DEFUP, 7, 0 };

魔法構成の意図

  • 強力な全体イメージの攻撃
  • 大きく回復して長期戦に
  • 攻撃力上昇で緊張感を維持
  • 防御で戦闘を引き延ばす。

ラスボスらしい、
粘り強く怖い戦闘 を演出しています。

バトル関数は共通で使う

ラスボス戦でも、
戦闘処理自体は同じ関数を使います。

int win = battle(&gs, boss);

共通関数を使うメリット

  • コードの重複がない。
  • バグが増えにくい。
  • メンテナンスが簡単

違いは、
is_boss フラグだけ です。

勝利時の特別処理

ラスボスに勝利すると、
通常戦とは違う分岐に入ります。

if (win) {
    gs.game_clear = 1;
    show_ending();
    break;
}

ここで行っていること

  1. ゲームクリアフラグを立てる。
  2. エンディング画面を表示
  3. メインループを抜ける。

この break により、
ゲームは自然に終了へ向かいます。

敗北時の処理も特別扱い

もしラスボスに敗北した場合は、
タイトル画面へ戻されます。

else {
    clear_screen();
    printf("マスタードラゴンに敗北した…\n");
    printf("Enterでタイトルへ...");
    read_line(buf, sizeof(buf));

    show_title();
    load_map_template(gs.map);
    gs.px = 1; gs.py = 1;
    init_characters(gs.party);
    memset(gs.inv, 0, sizeof(gs.inv));
}

なぜゲームオーバーにしないのか

  • 何度でも挑戦できる。
  • 学習用RPGとして親切
  • ストレスを減らす。

やり直しやすさ も、
良い設計のポイントです。

エンディング表示処理

エンディングは、
専用の関数で表示されます。

static void show_ending(void) {
    clear_screen();
    printf("THE END\n");
    printf("世界に平和が戻った…\n");
}

関数に分ける理由

  • main 関数が読みやすくなる。
  • 将来の演出追加が簡単
  • 処理の意味が明確になる。

表示処理も、
立派なロジックの一部 です。

ゲームを終わらせる設計の考え方

STEP20で重要なのは、
単にボスを倒すことではありません。

  • 勝利と敗北を明確に分ける。
  • 特別な存在として扱う。
  • ゲームの終わりを明示する。

これらが揃って、
「完成したRPG」になります。

STEP20の重要ポイントまとめ

STEP20で押さえておきたい点はこちらです。

  • ラスボスは固定データで生成する。
  • 通常戦と同じ battle 関数を使う。
  • is_boss フラグで挙動を分岐する。
  • 勝利後はエンディングへ
  • 敗北時も再挑戦できる設計にする。