
C言語入門|補足編:画面制御・効果音・色表示・安全な入力処理-RPGを快適にする裏方プログラム解説
はじめに:ゲームの「遊びやすさ」を支える存在
STEP1~STEP21では、
バトル・成長・マップ・イベントといった
RPGの主役となるロジック を中心に解説してきました。
しかし、実際に遊んでみると気づくと思います。
- 画面が毎回きれいに切り替わる。
- 攻撃や回復で音が鳴る。
- 文字に色がついて分かりやすい。
- 入力ミスでもゲームが壊れない。
これらはすべて、
裏方として支えている補助的なプログラム のおかげです。
この記事では、
STEP1~STEP21で詳しく触れられなかった
次の4つをまとめて解説します。
- 画面制御(簡易)
- 効果音(ビープ)
- ANSIカラー
- 入力ヘルパ関数
画面制御(簡易):毎回きれいな画面を作る仕組み
まずは画面制御から見ていきましょう。
void clear_screen(void) {
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
}この関数は何をしているのか
| OS | 実行されるコマンド |
|---|---|
| Windows | cls |
| Linux / Mac | clear |
画面を一度消してから再描画する
これがこの関数の役割です。
なぜ OS 判定が必要なのか
Windows と Linux/Mac では、
画面クリアのコマンドが違います。
- Windows では cls
- Linux / Mac では clear
そのため、次のように分岐しています。
#ifdef _WIN32これは、
- Windows 環境でコンパイルされたときだけ
- 中の処理を有効にする。
という意味です。
なぜ関数にしているのか
もし毎回、
system("clear");と書いていたら、
OS対応がとても大変になります。
関数にまとめておくことで、
- 呼び出しは clear_screen() だけ
- OS差分は内部に隠蔽
という、きれいな設計になります。
効果音(ビープ):音だけで状況を伝える工夫
次は効果音です。
static void sfx_beep(int kind) {
#ifdef _WIN32
switch (kind) {
case 0: Beep(880, 60); break;
case 1: Beep(660, 60); break;
case 2: Beep(988, 60); break;
case 3: Beep(523, 80); Beep(659, 80); Beep(784, 120); break;
default: Beep(200, 120); break;
}
#else
(void)kind;
printf("\a");
fflush(stdout);
#endif
}効果音の役割
| kind | 意味 |
|---|---|
| 0 | 決定音 |
| 1 | 攻撃 |
| 2 | 回復 |
| 3 | 勝利 |
| 4 | 警告 |
画面を見なくても、
- 攻撃した。
- 回復した。
- 危険な操作をした。
と分かるようになります。
Windows とそれ以外の違い
Windows の場合
Beep(周波数, ミリ秒);- 周波数で音の高さを変える。
- 長さで効果音の雰囲気を出す。
複数回鳴らすことで、
簡単なメロディも表現できます。
Linux / Mac の場合
printf("\a");これは 端末ベル と呼ばれる仕組みです。
- 環境によって鳴らないこともある。
- それでも簡単に実装できる。
学習用としては十分な方法です。
なぜ kind を使うのか
if や switch をあちこちに書く代わりに、
sfx_beep(1);と書くだけで
意図した音を鳴らせる ようになります。
これも「処理の意味を関数名に込める」
良い設計例です。
ANSIカラー:文字だけで情報を分かりやすくする
次は ANSIカラーです。
#define RED "\x1b[31m"
#define GREEN "\x1b[32m"
#define RESET "\x1b[0m"ANSIカラーとは
ANSIエスケープシーケンスを使うことで、
端末に色付き文字を表示できます。
| 色 | コード |
|---|---|
| 赤 | 31 |
| 緑 | 32 |
| 黄 | 33 |
| 青 | 34 |
| 紫 | 35 |
| 水色 | 36 |
| 白 | 37 |
使い方の例
printf(RED "敵が現れた!\n" RESET);- RED で色を変更
- RESET で元に戻す。
RESET を忘れると、
その後の文字も全部同じ色になるので注意です。
なぜマクロにしているのか
もし毎回、
printf("\x1b[31m");と書くと、
意味が分かりにくくなります。
RED
GREENという名前を付けることで、
コードが読みやすくなる のが大きな利点です。
入力ヘルパ:安全にユーザー入力を受け取る
最後に入力処理です。
文字列入力用ヘルパ
static void read_line(char* buf, size_t n) {
if (fgets(buf, (int)n, stdin) == NULL) {
buf[0] = '\0';
return;
}
size_t len = strlen(buf);
if (len && buf[len - 1] == '\n') buf[len - 1] = '\0';
}この関数の役割
- fgets で安全に入力を受け取る。
- 改行文字を削除する。
- 入力失敗時は空文字列にする。
scanf を使わない理由 は、
入力ミスで暴走しやすいからです。
数値入力用ヘルパ
static int read_int_safely(int* out) {
char buf[64];
read_line(buf, sizeof(buf));
if (buf[0] == '\0') return 0;
char* end = NULL;
long v = strtol(buf, &end, 10);
if (end == buf) return 0;
*out = (int)v;
return 1;
}なぜこの形が安全なのか
| 工夫 | 理由 |
|---|---|
| 文字列で受け取る | 入力崩れ防止 |
| strtol を使用 | 数値変換の安全性 |
| 戻り値で成否判定 | エラー対応が簡単 |
これにより、
- abc と入力されても落ちない。
- 空入力でも問題なし。
- 数値だけを正しく扱える。
という、堅牢な入力処理になります。
この補足コードがRPG全体にもたらした効果
これらの補助プログラムにより、
- 画面が見やすく
- 操作が分かりやすく
- ミスに強く
- 遊びやすい
RPGになっています。
派手ではありませんが、
完成度を大きく引き上げる重要な要素 です。
補足編まとめ
- clear_screen は OS差を吸収する画面制御
- sfx_beep は音で状況を伝える演出
- ANSIカラーは情報を視覚的に整理する。
- 入力ヘルパは安全性と安定性を支える。
これらは、
「動く」だけでなく「気持ちよく動く」
プログラムを書くための基本技術です。
これで
👉 rpg1.c 解説シリーズは完全終了 です 🎉
