色ブロックを表示する
色ブロックを表示する
「src\ColorBlock.c」ファイルを新規作成し、「Source Files」を右クリックして「Add」→「Existing Item」メニューでColorBlock.cファイルを追加します。
次に「include\ColorBlock.h」ファイルを新規作成し、「Header Files」を右クリックして「Add」→「Existing Item」メニューでColorBlock.hファイルを追加します。「ColorBlock」構造体は色ブロック1個ずつの設計図のようなものです。メインループで、この構造体を使って移動する色ブロックを表示します(図3)。
ここで「メインループ」とはゲーム全体のループを指しますが、本連載の他の言語ではメインループは「色ブロックが出ている間のゲームループ中」を指しているので混同するかもしれませんが、いつものように「MAIN_LOOP」という名前を使っています。
・サンプルコード「ColorBlock.h」ファイル
#ifndef COLORBLOCK_H
#define COLORBLOCK_H
#include "raylib.h"
typedef struct {
float x;
float y;
float vx;
float vy;
int width;
int height;
int color;
} ColorBlock;
void ColorBlock_Init(ColorBlock* block, int c, int w, int h);
int ColorBlock_Draw(ColorBlock* block, Texture2D img[]);
#endif【サンプルコードの解説】
「COLORBLOCK_H」で、このヘッダーファイルをコンパイルする際に重複しないようにします。
ColorBlock構造体を宣言し、(x,y)座標、幅高さ(width,height)、移動量(vx,vy)と色「color」変数を宣言します。初期化「ColorBlock_Init」関数と描画「ColorBlock_Draw」関数を宣言します。
・サンプルコード「ColorBlock.c」ファイル
#include "ColorBlock.h"
#include <stdlib.h>
void ColorBlock_Init(ColorBlock* block, int c, int w, int h) {
block->x = rand() % 1700;
block->y = rand() % 800;
block->vx = (rand() % 401) / 1000.0f - 0.2f;
block->vy = (rand() % 401) / 1000.0f - 0.2f;
block->width = w;
block->height = h;
block->color = c;
}
int ColorBlock_Draw(ColorBlock* block, Texture2D img[]) {
block->x += block->vx;
block->y += block->vy;
DrawTexture(img[block->color], (int)block->x, (int)block->y, WHITE);
if (block->x < block->width ||
block->y < block->height ||
block->x > 1800 ||
block->y > 900) {
return 0;
}
return 1;
}【サンプルコードの解説】
"ColorBlock.h"と、ランダム関数のために<stdlib.h>をインクルードします。
ColorBlock_Init関数でランダムな(x,y)と(vx,vy)をセットし、幅高さ色をセットします。
ColorBlock_Draw関数で色ブロックの座標を移動し、描画し、画面外に出たら戻り値として0を返し、それ以外は1を返します。
・サンプルコード「main.c」ファイル
#include "ColorBlock.h"
#include "resource_dir.h"
#define MAX_TEXTURES 6
#define MAX_SOUNDS 4
#define MAX_BLOCKS 300
typedef enum { TITLE,MAIN_LOOP,GAME_OVER,STAGE_CLEAR } GameState;
GameState game_state = TITLE;
Texture2D img[MAX_TEXTURES];
Sound snd[MAX_SOUNDS];
ColorBlock colors[MAX_BLOCKS];
int colorCount = 0;
int stage = 2;
Color bg = { 255,255,255,255 };
void init(void) {
colorCount = stage * 3;
for (int i = 0; i < colorCount; i++)
ColorBlock_Init(&colors[i], i % 3, img[0].width, img[0].height);
}
void title(void) {
(中略)
}
void main_loop(void) {
int flg = 0;
for (int i = 0; i < colorCount; i++)
flg += ColorBlock_Draw(&colors[i], img);
}
int main(void) {
SetConfigFlags(FLAG_VSYNC_HINT | FLAG_WINDOW_HIGHDPI);
InitWindow(1800, 900, "Color");
SetTargetFPS(60);
InitAudioDevice();
SearchAndSetResourceDir("resources");
img[0] = LoadTexture("0.png");
img[1] = LoadTexture("1.png");
img[2] = LoadTexture("2.png");
img[3] = LoadTexture("Title.png");
img[4] = LoadTexture("GameOver.png");
img[5] = LoadTexture("StageClear.png");
snd[0] = LoadSound("Mix.ogg");
snd[1] = LoadSound("GameStart.ogg");
snd[2] = LoadSound("GameOver.ogg");
snd[3] = 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 < MAX_TEXTURES; i++)
UnloadTexture(img[i]);
for (int i = 0; i < MAX_SOUNDS; i++)
UnloadSound(snd[i]);
CloseAudioDevice();
CloseWindow();
return 0;
}【サンプルコードの解説】
ColorBlock構造体の「colors」配列と「stage」変数を宣言します。最初のステージは2です。
「init」関数で色ブロックをstageの3倍(赤緑青3色)に初期化します。
ゲームループ中の「main_loop」関数で色ブロックを描画します。
「main」関数で、メインループ中のゲームループ(MAIN_LOOP)中にmain_loop関数を呼び出します。
ゲームオーバー画面を表示する
全ての色ブロックが画面外に出て1個もなくなったらゲームオーバー画面に遷移します(図4)。ゲームオーバー画像を中央に描画して、画面をどこでもクリックしたらタイトル画面に戻ります。
・サンプルコード「main.c」ファイル
(前略)
void init(void) {
(中略)
}
void title(void) {
(中略)
}
void main_loop(void) {
int flg = 0;
for (int i = 0; i < colorCount; i++)
flg += ColorBlock_Draw(&colors[i], img);
if (flg == 0) {
game_state = GAME_OVER;
PlaySound(snd[2]);
}
}
void game_over(void) {
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
game_state = TITLE;
DrawTexture(img[4],
(1800 - img[4].width) / 2,
(900 - img[4].height) / 2,
WHITE);
}
int main(void) {
(中略)
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関数を呼び出します。
水の波紋が円ではなく他の何らかの形をしていたら、と3DCGアニメをテストで作ってみました。でも上手くデザインできませんでした。Xで公開してしまったけど、ちょっと見せたくありません。Sora2で上手く作れるかもしれませんが、もうSora2は使えないのかな?
この記事をシェアしてください
