「C/C++」の「RayLib」でコンソールゲーム「Color」を開発してみよう
第8回の今回は、プログラミング言語「C/C++」の「RayLib」ライブラリを使ってコンソールゲーム「Color」を作る解説をします。
6:30
はじめに
この連載では、さまざまなプログラミング言語やライブラリで同じゲームを開発することで、容易にそのプログラミング言語に入門します。
第8回の今回はプログラミング言語「C/C++」を使って、次のURLのようなColorゲームを作ります。こちらからアセットをダウンロードしておいてください。
コンソールアプリはデスクトップアプリではありますが、昔で言うMS-DOSに当たるターミナルから起動するアプリです。
Colorゲームについて
Colorゲームの内容は第1回でも解説した通り、ゲームを開始したら、赤緑青の色ブロックをクリックします。すると背景色にその色が混ぜられるので、どんどんクリックして真っ白な背景にしていこうというゲームです。
プログラミング言語について
プログラミング言語「C/C++」はベル研究所が開発した、アプリやカーネルなど低レベルな(より深い層でという意味で)処理速度が要求される場面で使われる言語です。機械寄りのC言語にオブジェクト指向を加えたのがC++言語で、大規模開発で威力を発揮するのが特徴です。
RayLibについて
「RayLib」はプログラミング言語C/C++で2Dグラフフィックスを扱うゲームなどのコンソールアプリを開発できるライブラリです。シンプルに関数をまとめてくれているので、C/C++プログラミング入門用に非常に向いています。
※はっきりとは分からないのですが、コメントアウトなどで全角文字を書くとバグがあるようです。画面が真っ黒になったらアンドゥしてバグを探してみてください。
開発のために必要となる環境の準備
今回必要となる、無料版の「Visual Studio 2026」(以下、VS2026)を準備します。次のURLからVisual StudioインストーラーをダウンロードしてVS2026の「C++によるデスクトップ開発」をインストールしてください。
また、Windows以外にもmacOSやLinuxでも開発できますが、それらの開発環境のセットアップ方法は次で説明する「raylib-quickstart」の「README.md」を参考にしてください。
プロジェクトを作成しよう
GitHubから「raylib-quickstart-main」をダウンロードし、解凍して「build-VisualStudio2026.bat」を実行するとプロジェクトが作成されます。
VS2026を起動し、「Open a project or solution」メニューでプロジェクトの中に生成された「raylib-quickstart-main.slnx」ファイルを開きます。
次の階層図のように、必ず「images」フォルダ内の画像は「resources」フォルダに、「sounds」フォルダ内のサウンドはresourcesフォルダに、「.cpp」ファイルは「src」フォルダに、「.h」ファイルは「include」フォルダに配置します。
なお、今回のライブラリはサウンドがシンプルに扱えるため、サウンドも使います。
・階層図
raylib-quickstart-mainフォルダ
┠raylibフォルダ(RayLibライブラリフォルダ)
┃┠Referencesフォルダ
┃┠External Dependenciesフォルダ
┃┠Header Files
┃┗Source Files
┗raylib-quickstart-mainフォルダ(メインフォルダ)
┠Referencesフォルダ
┠External Dependenciesフォルダ
┠Game Resouce Files(resourcesフォルダ)
┃┠0.pngファイル(赤の色ブロック画像)
┃┠1.pngファイル(緑の色ブロック画像)
┃┠2.pngファイル(青の色ブロック画像)
┃┠GameClear.oggファイル(ゲームクリアサウンド)
┃┠GameOver.oggファイル(ゲームオーバーサウンド)
┃┠GameOver.pngファイル(ゲームオーバー画像)
┃┠Mix.oggファイル(混色サウンド)
┃┠StageClear.oggファイル(ステージクリアサウンド)
┃┠StageClear.pngファイル(ステージクリア画像)
┃┗Title.pngファイル(タイトル画像)
┠Header Files(includeフォルダ)
┃┠ColorBlock.hファイル(色ブロックヘッダー)
┃┗resource_dir.hファイル(リソースパスヘッダー)
┠Source Files(srcフォルダ)
┃┠ColorBlock.cppファイル(色ブロックファイル)
┃┗main.cppファイル(メインファイル)
┗Windows Resource Files(includeフォルダ)
┠application.rc
┗icon.ico「main.c」ファイルの拡張子を、CだけでなくC++も使えるように「main.cpp」に変更します。
次のサンプルコードをコーディングし、「Debug」→「Start Debugging」メニューを実行すると真っ白なウィンドウが表示されます(図1)。まだテンプレートからウィンドウサイズを大きくして画像と文字を消し、背景色を真っ白にしただけです。
・サンプルコード「main.cpp」ファイル
#include "resource_dir.h"
Color bg = { 255, 255, 255, 255 };
int main() {
SetConfigFlags(FLAG_VSYNC_HINT | FLAG_WINDOW_HIGHDPI);
InitWindow(1800, 900, "Color");
SetTargetFPS(60);
while (!WindowShouldClose()) {
BeginDrawing();
ClearBackground(bg);
EndDrawing();
}
CloseWindow();
return 0;
}【サンプルコードの解説】
リソースヘッダーをインクルードすると、その中でraylibヘッダーもインクルードされます。
「main」関数がアプリ起動時に最初に呼ばれる関数です。
コンフィグをセットします。
ウィンドウを初期化します。
60FPS(1秒間に60コマ画面を更新)にセットします。
while文がメインループです。
描画を開始(「BeginDrawing」関数)します。
背景色を真っ白(「bg」変数)にします。
描画を終了(「EndDrawing」関数)します。
ウィンドウを閉じます。
main関数から戻り値で0を返します。
タイトル画面を表示する
まずタイトル画像を表示します(図2)。タイトル画面をどこでもクリックしたら「ゲームスタート」という音声とともにゲームを開始し、タイトル画像が消えます。画像の「Texture」クラスとサウンドの「Sound」クラスはSTLの<vector>で管理することで、メモリの解放を明記しなくても自動で解放してくれます。
・サンプルコード「main.cpp」ファイル
#include "resource_dir.h"
#include <vector>
enum GameState { TITLE, MAIN_LOOP, GAME_OVER, STAGE_CLEAR };
GameState game_state = TITLE;
std::vector<Texture> img;
std::vector<Sound> snd;
Color bg = { 255, 255, 255, 255 };
void init() {
}
void title() {
Vector2 mouse = GetMousePosition();
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
game_state = MAIN_LOOP;
init();
PlaySound(snd[1]);
}
DrawTexture(img[3], (1800 - img[3].width) / 2, (900 - img[3].height) / 2, WHITE);
}
int main() {
SetConfigFlags(FLAG_VSYNC_HINT | FLAG_WINDOW_HIGHDPI);
InitWindow(1800, 900, "Color");
SetTargetFPS(60);
InitAudioDevice();
SearchAndSetResourceDir("resources");
img.push_back(LoadTexture("0.png"));
img.push_back(LoadTexture("1.png"));
img.push_back(LoadTexture("2.png"));
img.push_back(LoadTexture("Title.png"));
img.push_back(LoadTexture("GameOver.png"));
img.push_back(LoadTexture("StageClear.png"));
snd.push_back(LoadSound("Mix.ogg"));
snd.push_back(LoadSound("GameStart.ogg"));
snd.push_back(LoadSound("GameOver.ogg"));
snd.push_back(LoadSound("StageClear.ogg"));
while (!WindowShouldClose()) {
BeginDrawing();
ClearBackground(bg);
switch (game_state) {
case TITLE: title(); break;
}
EndDrawing();
}
for (int i = 0; i < img.size(); i++) UnloadTexture(img[i]);
CloseAudioDevice();
CloseWindow();
return 0;
}【サンプルコードの解説】
<vector>をインクルードします。
ゲーム状態をTITLEにセットします。
Textureクラスのimg配列と、Soundクラスのsnd配列を宣言します。
「init」関数はステージ開始時に呼ばれます。
「title」関数でマウス座標を「mouse」変数に取得し、タイトル画像を描画し、マウス左ボタンが押されたらメインループに遷移します。
main関数でオーディオデバイスを初期化し、"resources"フォルダをリソースディレクトリに指定し、画像とサウンドをすべて読み込みます。whileのメインループでtitle関数を呼び出し、メインループを抜けたらテクスチャをアンロードしてオーディオデバイスを閉じます。
かるたの代わりに、本の各ページを使って競技かるたのようなことができたらいいですね。百人一首ではなく歴史人物の経歴でかるたをすれば、日本史・世界史の勉強にもなるのではないでしょうか?
- この記事のキーワード
この記事をシェアしてください
