書籍「ゲームプログラミングC++」を読み進めています。
Chapter2の課題にかなり苦戦したので
整理するのに使用したメモと行ったことを
雑にですが残しておきます。
記載している内容に誤りが含まれていたらすみません。
ゲームプログラミングC++ Chapter2の課題
— Meiryo (@Meiryo_Pro) 2023年6月21日
アニメーション切り替えと
タイルセットからタイルを読み込んでマップ作成
やっとできた。 pic.twitter.com/bLCIGfMBQS
クラス図
処理の流れ
ShipがGameに所持されるまでの流れ
- Game::LoadData()でShipが作られる
- ShipのコンストラクタでActorのコンストラクタを呼ぶ
(ShipはActorの子クラス) - ActorのコンストラクタでGame::AddActorが実行される
- Game::UpdateGameでmActorsに追加される
ShipのAnimSpriteConponentの流れ
- Shipのコンストラクタで作られる
- AnimSpriteConponentのコンストラクタで
SpriteComponentのコンストラクタが呼ばれる - SpriteComponentのコンストラクタで
Componentのコンストラクタが呼ばれる - Componentのコンストラクタで
ActorのAddConponentが呼ばれる
(ComponentはActorの参照を持つ) - AddComponentでmComponentsに追加される
- SpriteComponentのコンストラクタでActor→GetGame()→AddSprite(this)
- AddSpriteでGameのmSpritesに追加される
課題2.2
AnimSpriteComponentに二次元配列を用意し
「移動」「ジャンプ」「攻撃」アニメーションテクスチャを
それぞれ格納しました。
アニメーションがLoopするか否かは
フラグを用意し入力をするときに切り替えました。
if (state[SDL_SCANCODE_W]) { mDownSpeed -= 300.0f; mAsc->SetCurrentAnimIndex(0); mAsc->SetLoopAnim(true); } if (state[SDL_SCANCODE_SPACE]) { mAsc->SetCurrentAnimIndex(1); mAsc->SetLoopAnim(true); } if (state[SDL_SCANCODE_C]) { mAsc->SetCurrentAnimIndex(2); mAsc->SetLoopAnim(true); }
補足
■綺麗にするのであれば二次元配列ではなく
enum型を使用したMapのとかの方が良さそうですが
手抜きしました。
■PlayerにAnimSpriteComponentを
持たせてしまっています。
class Player :public Actor { private: float mRightSpeed; float mDownSpeed; AnimSpriteComponent* mAsc; };
これはここに行き着くまでに
ActorのmComponentsに格納されている
AnimSpriteComponentを使用して
AnimSpriteComponentに実装した
SetCurrentAnimIndex()とSetLoopAnim()を使用したいmComponentから取得するにはどうやっても重いらしい
dynamic_castが必要そうそれを頻繁に呼び出して良いものだろうか
もしかしてAnimSpriteComponentから
Actorの状態を見てアニメーションを
切り替えるのが正解なのでは?
等を試したり考えたりしましたが
うまく行かず答えが出ずかなりの時間を
使ってしまったので諦めました。
どこかで学べるはずなので一旦保留します。
課題2.3
情報
- MapLayerの列の数=24 行の数=32
- タイルセットの列の数=8 行の数= 24
- Tileのサイズは32*32
MapLayerのタイル番号とタイルセットのタイルの紐づけ
下図は実装する時に使ったタイルセットのメモです。
タイル番号をKey、y座標とx座標のペアをValueにした
Mapを作成して紐づけました。
int count = 0; //タイルセットの行の数 for (int i = 0; i < kHeightChipNum; i++) { //タイルセットの列の数 for (int j = 0; j < kWidthChipNum; j++) { mTileSetInfos.emplace(count, std::make_pair(i, j)); count++; } }
補足
最初は
「18番タイル」のx座標は(計算式)、y座標は(計算式)
みたいな感じで計算で紐づけできないかなと
考えたのですがわかりませんでした。
マップの描画方法
こちらの動画が参考になりました。