ゲーム実装で身に付くプログラミング 8

色ブロックを表示する

色ブロックを表示する

「src\ColorBlock.cpp」ファイルを新規作成し、「Source Files」を右クリックして「Add」→「Existing Item」メニューでColorBlock.cppファイルを追加します。タイトル画面でマウスを押したらゲーム画面に遷移し、色ブロックが複数表示されて移動し、画面外に出たら削除されましたね(図3)。

同様に「include\ColorBlock.h」ファイルを新規作成し、「Header Files」を右クリックして「Add」→「Existing Item」メニューでColorBlock.hファイルを追加します。「ColorBlock」クラスは色ブロック1個ずつの設計図のようなものです。

ここではメインループはゲーム全体のループを指しています。本連載の他の言語では色ブロックが出ている間のゲームループを指しているため混同するかもしれませんが、MAIN_LOOPという名前はいつものように使っています。

図3:色ブロックを表示

・サンプルコード「ColorBlock.h」ファイル

#pragma once

#include "raylib.h"
#include <vector>

class ColorBlock
{
public:
	float x, y, width, height, vx, vy;
	int color;

	ColorBlock(int c,int w,int h);
	int Draw(std::vector<Texture> img);
};

【サンプルコードの解説】
「#pragma once」でヘッダーファイルがコンパイルの際に重複してインクルードされないようにします。
ColorBlockクラスを宣言し、(x,y)座標、幅(width)、高さ(height)、移動量(vx,vy)と色「color」変数を宣言します。コンストラクタと描画「Draw」メソッドを宣言します。

・サンプルコード「ColorBlock.cpp」ファイル

#include "ColorBlock.h"
#include <cstdlib>

ColorBlock::ColorBlock(int c,int w,int h) {
	x = rand() % 1700;
	y = rand() % 800;
	vx = (rand() % 401)/1000.0 - 0.2;
	vy = (rand() % 401)/1000.0 - 0.2;
	width = w;
	height = h;
	color = c;
}

int ColorBlock::Draw(std::vector<Texture> img) {
	x += vx;
	y += vy;
	DrawTexture(img[color], x, y, WHITE);
	if (x < width || y < height || x > 1800 || y > 900) return 0;
	return 1;
}

【サンプルコードの解説】
"ColorBlock.h"と、ランダム関数のために<cstdlib>をインクルードします。
コンストラクタでランダムな(x,y)と(vx,vy)をセットし、幅、高さ、色をセットします。
Drawメソッドで色ブロックの座標を移動し、描画し、画面外に出たら戻り値として0を返し、それ以外は1を返します。

・サンプルコード「main.cpp」ファイル

#include "ColorBlock.h"
#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;
std::vector<ColorBlock> colors;
int stage = 2;
Color bg = { 255, 255, 255, 255 };

void init() {
	colors.clear();
	for (int i = 0; i < stage * 3; i++) colors.push_back(ColorBlock(i % 3, img[0].width, img[0].height));
}

void title() {
(中略)
}

void main_loop() {
	int flg = 0;
	for (auto it = colors.begin(); it != colors.end(); it++) flg += it->Draw(img);
}

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;
			case MAIN_LOOP:
				main_loop();
				break;
		}
		EndDrawing();
	}
	for (int i = 0; i < img.size(); i++) UnloadTexture(img[i]);
	CloseAudioDevice();
	CloseWindow();
	return 0;
}

【サンプルコードの解説】
ColorBlockクラスの「colors」配列と「stage」変数を宣言します。ステージは最初は2です。
「init」関数で色ブロックをstageの3倍(赤緑青3色)追加します。
ゲームループ中の「main_loop」関数で色ブロックを描画します。
「main」関数で、メインループ中のゲームループ(MAIN_LOOP)中にmain_loop関数を呼び出します。

ゲームオーバー画面を表示する

全ての色ブロックが画面外に出て1個もなくなったらゲームオーバー画面に遷移します(図4)。ゲームオーバー画像を中央に描画して、画面をどこでもクリックしたらタイトル画面に戻ります。

図4:ゲームオーバー画面の表示

・サンプルコード「main.cpp」ファイル

(前略)

void init() {
(中略)
}

void title() {
(中略)
}

void main_loop() {
	int flg = 0;
	for (auto it = colors.begin(); it != colors.end(); it++) flg += it->Draw(img);
	if (flg == 0) {
		game_state = GAME_OVER;
		PlaySound(snd[2]);
	}
}

void game_over() {
	Vector2 mouse = GetMousePosition();
	if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
		game_state = TITLE;
	}
	DrawTexture(img[4], (1800 - img[4].width) / 2, (900 - img[4].height) / 2, WHITE);
}

int main() {
(中略)
	while (!WindowShouldClose()) {
		BeginDrawing();
		ClearBackground(bg);
		switch (game_state) {
			case TITLE: title(); break;
			case MAIN_LOOP:
				main_loop();
				break;
			case GAME_OVER: game_over(); break;
		}
		EndDrawing();
	}
(中略)
}

【サンプルコードの解説】
main_loop関数で色ブロックの数が0個になったら「game_state」変数をゲームオーバーにし、"GameOver.ogg"サウンドを再生します。
「game_over」関数で"GameOver.png"画像を描画します。マウスを左クリックするとgame_state変数をタイトルにします。
main関数のメインループ中で、ゲームオーバー時にgame_over関数を呼び出します。

【コラム】Detox to Earn

スマホを5時間以上使う人が沢山いるというので「スマホ断食」というコンセプトのNFTアプリを考えました。スマホを使わないほどギャラが貰えるアプリです。

デジタルデトックスアプリもありますが、イーサリアムでインセンティブがあれば差別化できます。iPhoneとiPadのスクリーンタイムAPIを使ったら作れるのかな?

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored