Meiryo’s blog

やってみて詰まったことを備忘録として残すブログ

【ゲームプログラミングC++】Chapter2と課題のメモ

書籍「ゲームプログラミングC++」を読み進めています。

Chapter2の課題にかなり苦戦したので
整理するのに使用したメモと行ったことを
雑にですが残しておきます。

記載している内容に誤りが含まれていたらすみません。

クラス図

処理の流れ

ShipがGameに所持されるまでの流れ

  1. Game::LoadData()でShipが作られる
  2. ShipのコンストラクタでActorのコンストラクタを呼ぶ
    (ShipはActorの子クラス)
  3. ActorのコンストラクタでGame::AddActorが実行される
  4. Game::UpdateGameでmActorsに追加される

ShipのAnimSpriteConponentの流れ

  1. Shipのコンストラクタで作られる
  2. AnimSpriteConponentのコンストラクタで
    SpriteComponentのコンストラクタが呼ばれる
  3. SpriteComponentのコンストラクタで
    Componentのコンストラクタが呼ばれる
  4. Componentのコンストラクタで
    ActorのAddConponentが呼ばれる
    (ComponentはActorの参照を持つ)
  5. AddComponentでmComponentsに追加される
  6. SpriteComponentのコンストラクタでActor→GetGame()→AddSprite(this)
  7. 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座標は(計算式)
みたいな感じで計算で紐づけできないかなと
考えたのですがわかりませんでした。

マップの描画方法

こちらの動画が参考になりました。