
C言語入門|STEP18:マップ探索ロジックの実装-2次元配列・移動判定・イベント分岐
はじめに:RPGはマップを歩いてこそ始まる
STEP17では、アイテムと装備の仕組みを解説しました。
STEP18では、RPGの「冒険感」を支える マップ探索ロジック に注目します。
このRPGでは、
- 文字で描かれたマップ
- プレイヤーの移動
- 敵・宝箱・イベントの発生
を 2次元配列 を使って実装しています。
一見難しそうですが、仕組み自体はとても素直です。
マップは2次元配列で表現する
まず、マップは次のように定義されています。
#define MAP_W 25
#define MAP_H 25
static char g_map[MAP_H][MAP_W];なぜ2次元配列なのか
| 理由 | 内容 |
|---|---|
| 直感的 | 縦横の座標が分かりやすい。 |
| 表示しやすい | そのまま画面に描画できる。 |
| 判定が簡単 | 壁・イベント確認が容易 |
RPGのマップは、
配列と非常に相性が良い構造 です。
マップに使われている記号の意味
マップ内では、1文字が1マスを表します。
| 記号 | 意味 |
|---|---|
| # | 壁(通行不可) |
| . | 通路 |
| @ | プレイヤー |
| E | 敵 |
| T | 宝箱 |
| I | イベント |
| B | ボス |
文字だけで状態を表現できるため、
デバッグもしやすくなっています。
マップの初期化処理
ゲーム開始時には、
マップを初期化します。
static void init_map(void) {
for (int y = 0; y < MAP_H; y++) {
for (int x = 0; x < MAP_W; x++) {
g_map[y][x] = '.';
}
}
}この処理のポイント
- 全マスを通路で初期化
- 壁やイベントは後から配置
まず「空の世界」を作ってから、
要素を配置する流れ になっています。
壁の配置で迷路を作る
壁は、別の処理で配置されます。
g_map[0][x] = '#';
g_map[MAP_H-1][x] = '#';なぜ外周を壁にするのか
- マップ外への移動を防ぐ。
- 移動判定が簡単になる。
外周を壁にしておくことで、
境界チェックを減らせます。
プレイヤーの位置管理
プレイヤーの位置は、
座標で管理されています。
int px = 1;
int py = 1;座標管理の基本
- x:横方向
- y:縦方向
配列アクセスでは
g_map[py][px]
という形になる点に注意しましょう。
マップ表示処理の考え方
マップは、
毎ターン描画されます。
for (int y = 0; y < MAP_H; y++) {
for (int x = 0; x < MAP_W; x++) {
if (x == px && y == py)
putchar('@');
else
putchar(g_map[y][x]);
}
putchar('\n');
}表示処理のポイント
- プレイヤー位置だけ特別扱い。
- マップ配列は背景扱い。
これにより、
プレイヤーが動いて見える ようになります。
移動入力の受け取り方
移動は、テンキー風の入力で行います。
| 入力 | 移動 |
|---|---|
| 8 | 上 |
| 2 | 下 |
| 4 | 左 |
| 6 | 右 |
int cmd;
scanf("%d", &cmd);この入力をもとに、
移動方向を決定します。
移動先が通行可能かの判定
移動前には、
必ず判定を行います。
if (g_map[ny][nx] == '#') {
printf("壁があって進めない!\n");
return;
}このチェックの意味
- 壁には入れない。
- マップ破壊を防ぐ。
移動前チェック は、
マップ探索の基本です。
マスに応じたイベント分岐
移動先のマスによって、
処理が分岐します。
switch (g_map[ny][nx]) {
case 'E': start_battle(); break;
case 'T': open_treasure(); break;
case 'I': trigger_event(); break;
}文字による分岐のメリット
- 1文字で状態が分かる。
- switch文で整理しやすい。
- 拡張が簡単
RPGのイベント処理は、
文字コード分岐が定番 です。
敵と遭遇したあとの処理
敵と戦闘したあとは、
そのマスを通路に戻します。
g_map[ny][nx] = '.';なぜ消すのか
- 同じ敵と何度も戦わない。
- マップが進行状態を覚える。
これにより、
探索済みエリアが分かる ようになります。
宝箱・イベントも一度きりにする理由
宝箱やイベントも、
処理後はマップから消えます。
g_map[ny][nx] = '.';この設計の効果
- 探索の意味が出る。
- 無限取得を防ぐ。
- シンプルな状態管理
一度きりのイベントは、
マップを書き換えるだけで実現できます。
ボスマス到達時の特別処理
ボスのマスでは、
通常とは違う処理に進みます。
if (g_map[ny][nx] == 'B') {
start_boss_battle();
}ここがゲームの山場
- 通常戦闘とは別扱い。
- エンディングへ直結
マップ探索と物語が、
ここでつながる構造 になっています。
STEP18で押さえておきたいポイントまとめ
STEP18の重要ポイントはこちらです。
- マップは2次元配列で管理する
- 1文字=1マスで状態を表す
- 移動前に必ず通行判定を行う
- マスの文字でイベントを分岐する
- 処理後はマップを書き換えて状態管理する
