色ブロックを表示する
色ブロックを表示する
「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という名前はいつものように使っています。
・サンプルコード「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)。ゲームオーバー画像を中央に描画して、画面をどこでもクリックしたらタイトル画面に戻ります。
・サンプルコード「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関数を呼び出します。
スマホを5時間以上使う人が沢山いるというので「スマホ断食」というコンセプトのNFTアプリを考えました。スマホを使わないほどギャラが貰えるアプリです。
デジタルデトックスアプリもありますが、イーサリアムでインセンティブがあれば差別化できます。iPhoneとiPadのスクリーンタイムAPIを使ったら作れるのかな?
- この記事のキーワード
この記事をシェアしてください
