====== 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 へ]] ;#;