====== Cosmic Hooligun 予告編 ======
==== 夏休みだもん、ゲーム。。。 ====
もう夏休みも終わりだし、さすがに追加はないかなと思った諸君。甘かったね\\
次作るゲームは、昔懐かしい(ってよくWebに書いてるけどどんな世代に向けて言ってんだろう。。。)スペースインベーダーに似たゲームを作っていこう。\\
スペースインベーダーはタイトーのゲームで、**Pong(Table TENNIS) => Break OUT(ブロック崩し) => スペースインベーダー => ギャラクシアン => ゼビウス**、の流れを作った現代のシューティングゲームの北京原人であり、ネアンデルタール人であり、ミトコンドリアであり、デオキシリボ核酸である。\\
これを知らず、作らずして、ほかのゲームを考えるとはおこがましいにもほどがあり、ゲームとは何かを考える良い機会でもあると思う。\\
とりあえず、初めの目標はこれ\\
{{game-engineer:classes:2023:something-else:summertime-special-cource:siv3d_app_debug_build_d3d11_145_fps_f_800x600_v_800x600_s_800x600_2023-08-23_16-59-19.mp4?300}}
とりあえずの目標、「弾撃って当たる」
予定では、ここまでに\\
シューティングゲームの基本動作ができるまでのヘッダファイルの中身
//Mainから直で呼ぶやつ
void UpdateTitle(gameData& _dat);
void DrawTitle(gameData& _dat);
void UpdatePlay(gameData& _dat);
void DrawPlay(gameData& _dat);
void UpdateClear(gameData& _dat);
void DrawClear(gameData& _dat);
void UpdateGameOver(gameData& _dat);
void DrawGameOver(gameData& _dat);
void InitGameData(gameData& _dat);
//Mainから直では呼ばないやつ
void InitPlayer(gameChar& _player);
void InitEnemy(gameChar& _enemy);
void SetCharaRect(gameChar& _gamechar, SizeF _size);
void InitPlayerBullet(gameData& _dat);
//void InitEnemyBullet(EnemyBullet& _eb);
direction GetDirection();
void UpdatePlayer(gameData& _dat);
void DrawPlayer(gameChar& _player);
void DrawEnemy(gameChar& _enemy);
//void UpdateEnemy(gameChar& _enemy);
int GetAlivePlayerBulllet(PlayerGun& _playerGun);
void FirePlayerBullet(gameData& _dat);
void UpdatePlayerBullet(PlayerGun& _playerGun);
void DrawPlayerBullet(PlayerGun& _playerGun);
//爆発関係
void InitExplosionFlames(Explosion& _explosion);
int GetAliveExplotion(Explosion& _explosion);
void FireFlame(Explosion& _explosion, Vec2 _pos);
void UpdateExplosion(Explosion& _explosion);
void DrawExplosions(Explosion& _explosion);
//当たり判定
void PlayerBulletVsEnemies(gameData& _dat);
なんか大変そうだよねぇ。。。\\
処理が複雑になってくると、こんな感じでたくさんの関数が増えてくる。\\
この関数たちを、目的によって呼び分けていかなければならないのだけれども、現在の構造体+関数型のプログラムでは簡略化に限界がある。\\
とりあえず今回はこのまま何とか作っていこうと思う。\\
まずは、準備として今回のファイル構成\\
- **gameSequence.h**
* ゲームに登場する関数たちと、構造体、グローバル変数の宣言が書いてある。
- **gameSequence.cpp**
* ゲームに登場する関数たちの本体(定義)が書き連ねられている
- **Main.cpp**
* 上の2つで作った関数を組み合わせて、ゲームのロジックを実行するためのファイル\\
今回から、めんどくさくなるのでglobals.hはやめておいた。\\
==== ゲームに使うデータたち ====
今までは全部バラバラにゲームのステートやプレイヤーの構造体などを持っておいて、関数に渡してきたが、だんだんあほくさくなってきたので__(本当は、必要ないものまで関数に変更可能な状態で渡すのは、誤変更などが起こり危険なので、あまり良くないが、)__今回は、ゲームに必要ないろんなデータを丸っと全部やり取りするようにしてみた。\\
ゲームに必要なデータが増えたら、\\
gameData構造体の作成
struct gameData
{
//ここに必要なデータを並べていく
};
ゲームに出てくる、オブジェクトはほぼすべて、以下の構造体で表される\\
gameChar型の追加
struct gameChar
{
Vec2 pos; //位置
bool isAlive; //生死
Texture tex; //画像
double speed; //動作速度
RectF rect; //バウンディングボックス
Vec2 moveDir; //方向ベクトル
};
* **Vec2 pos;**
* 位置(型:Vec2)
* キャラクタの(多分中心)位置 x、yの実数データ
* **bool isAlive;**
* 生死
* キャラクタの生死の情報 bool型
* **Texture tex; **
* 画像
* キャラクタの画像(アニメーションある時はアニメーションシート(後述))
* Texture型
* **double speed;**
* 移動速度
* **RectF rect; **
* バウンディングボックス
* キャラクタを囲む四角形、当たり判定や移動の処理で使う
* キャラクタと同じ大きさとは限らない
* **Vec2 moveDir;**
* 方向ベクトル
* この方向に speedで移動する
=== gameDataにプレイヤーと敵を一匹追加する ===
struct gameData
{
gameChar Enemy;
gameChar Player;
};
=== グローバルに使ういつものやつを追加 ===
globals.hを廃止したけど、そっちあったいつも使いそうなやつ(ゲームシーケンスに関するものなど)をgameSequence.hに移す\\
さすがに、今までと同じすぎるので説明は省略する。\\
いつものenumとかをgameSequence.hに追加
enum GAME_STATE
{
TITLE, PLAY, CLEAR, GAMEOVER
};
enum direction
{
UP, LEFT, DOWN, RIGHT, NONE
};
struct gameChar
{
Vec2 pos;
bool isAlive;
Texture tex;
double speed;
RectF rect;
Vec2 moveDir;
};
ついでにいつものゲームステートもgameDataに入れちゃおう。\\
struct gameData
{
GAME_STATE gState;
gameChar Enemy;
gameChar Player;
};
そんで、いつものゲームシーケンスをGAME_STATEではなく、gameDataを渡すようにしてしまおう。\\
いつものやつからMain.cppを以下のように変更しよう。\\
void Main()
{
gameData gDat;
gDat.gState = GAME_STATE::TITLE;
FontAsset::Register(U"font", FontMethod::MSDF, 48, Typeface::Bold);
while (System::Update())
{
switch (gDat.gState)
{
case TITLE:
UpdateTitle(gDat);
DrawTitle(gDat);
break;
case PLAY:
UpdatePlay(gDat);
DrawPlay(gDat);
break;
case CLEAR:
UpdateClear(gDat);
DrawClear(gDat);
break;
case GAMEOVER:
UpdateGameOver(gDat);
DrawGameOver(gDat);
break;
default:
break;
}
}
}
これで、一応、全部が全部グローバル変数状態、からは脱出して少し進化できると思おう。\\
いつも通り、クリックで以下のシーンを1周遷移できるようにソースコード書こう。(省略)\\
//Mainから直で呼ぶやつ
void UpdateTitle(gameData& _dat);
void DrawTitle(gameData& _dat);
void UpdatePlay(gameData& _dat);
void DrawPlay(gameData& _dat);
void UpdateClear(gameData& _dat);
void DrawClear(gameData& _dat);
void UpdateGameOver(gameData& _dat);
void DrawGameOver(gameData& _dat);
===== 画像を作成 =====
自機の画像は、みんなphotshop使えるんだから自分で作成してもいいし、フリーのゲーム素材を使ってもよいので入手しましょう。\\
Sprite(背景透過有り)のPng画像がいいと思う。\\
何も見つけられない人は[[https://opengameart.org/content/space-shooter-redux|Kennyさんとこの画像]]とか、[[https://github.com/sparklinlabs/superpowers-asset-packs#preview|この辺]]からダウンロードするとよい\\
僕は[[https://github.com/sparklinlabs/superpowers-asset-packs/tree/master/space-shooter/ships|この辺のやつ]]を使いましたよっと。\\
どれでもよいので、Sip3DプロジェクトのAppフォルダにimagesフォルダを作ってその下に入れとく。(と、フォルダとファイル名指定でファイル読み込めるので便利)\\
;#;
[[game-engineer:classes:2023:something-else:summertime-special-cource:cosmichooligun-2|Space Hooligun の制作その2 へ]]
;#;