本当は「RootJob」の下に「SceneManager」があって、その下に各シーンが来るのだが、一旦「SceneManager」は無視する。
PlaySceneクラスを作成し、RootJobの子供にしよう。
RootJob.cppでPlayScene.hをインクルードし、Initialize関数の中でPlaySceneオブジェクトを作る。
この時コンストラクタの引数には「親」を渡さなければならない。プレイシーンの親は……?
そして、すべてのゲームオブジェクトはchildList_というリストを持っているので、そこにPlaySceneオブジェクトを追加する。
#include "RootJob.h"
#include "●●●●●●●●●"
RootJob::RootJob()
{
}
RootJob::~RootJob()
{
}
void RootJob::Initialize(void)
{
PlayScene* pPlayScene;
pPlayScene = new PlayScene(●●●);
pPlayScene->Initialize();
childList_.●●●●●●(pPlayScene);
}
上のように書くと「childList_」のところでエラーが出る。
GameObject.hの方でアクセス指定を変更しよう。
先ほど書いた3行は、ゲームオブジェクトを追加するとに必ずセットで書くことになる。
何とかまとめられないだろうか。
ちなみに去年の資料を見ると、ゲームオブジェクトを追加するときは次のような書き方をしていた。
Instantiate<クラス名>(親);
この関数をまねしてGameObjectクラスに追加しよう。
とりあえずこんな感じ。
<GameObject.h>
virtual void Draw() = 0;
virtual void Release(void) = 0;
void Instantiate(GameObject* parent)
{
PlayScene* pPlayScene;
pPlayScene = new PlayScene(parent);
pPlayScene->Initialize();
childList_.push_back(pPlayScene);
}
}
しかし、これだと「PlayScene」しか作れない。
他のクラスのオブジェクトも作れるようには次のようにする。
まず「PlayScene」と書いたところを「T」に置き換える。
void Instantiate(GameObject* parent)
{
T* pPlayScene;
pPlayScene = new T(parent);
pPlayScene->Initialize();
childList_.push_back(pPlayScene);
}
そして、関数の宣言前に次のように書く。
template <class T>
void Instantiate(GameObject* parent)
{
ついでにローカル変数名も変えておこう。
T* p;
p = new T(parent);
p->Initialize();
childList_.push_back(p);
このように書くと「T」と書いた部分は、この関数を呼ぶときに何型にするかを決めることができる。
これを関数テンプレートと言う。
この関数を呼ぶためにはこう書く
void RootJob::Initialize(void)
{
Instantiate<PlayScene>(this);
}
このように、関数名と引数の間に<型名>を書く。
これで、自分(RootJob)を親としたPlaySceneが出来上がった。
上で作った関数の最後の行でchildListにデータを追加しているが、これだと全部「自分の子供」になってしまう。
引数で親が誰なのかを受け取っているので――
void Instantiate(GameObject* parent)
{
T* pPlayScene;
pPlayScene = new T(parent);
pPlayScene->Initialize();
parent->childList_.push_back(pPlayScene);
}
と書くのが正しい。