シーン管理 コーディング2
最近書いてないので続き書こうと思う。
前回で IGameScene と SceneController を書いた。
(前回はここ id:selvaggio:20060821:1156148509 )
間違ってたら遠慮なく指摘してください。
知らない間に修正します。
シーンクラスの実装
端的に何をしたいかと言えば、
SceneController *sc = new SceneController(); IGameScene *somescene = new SomeScene(sc); sc->regist(somescene); while(!sc->empty()){ sc->act(); }
こんな感じで使えるシーンクラスを作りたいわけだ。
このための外部仕様、すなわちインターフェイスは前回の IGameScene で規定してある。
すなわち、初期化・実行・後処理を行うわけだ。
後は、実行する中身を処理する関数を書けばいいわけだ。
最もシンプルな例
例えば、単に Hello, World! と表示するだけのシーンならば次のような感じになる。
#include <iostream> class HelloScene : public IGameScene { // IGameScene を public 継承 public: HelloScene(SceneController* sc){} int init(){} // なーんもせぇへん int play(){ std::cout << "Hello, World!" << std::endl; } int fin(){} // なーんもせぇへん }; int main(int, char**){ SceneController *sc = new SceneController(); IGameScene *hs = new HelloScene(sc); sc->regist(hs); while(!sc->empty()){ sc->act(); } delete hs; delete sc; return; }
こうすれば、 SceneController::act() から HelloScene::play() が呼び出されて、
Hello, World! と表示されるはずだ。
解説
クラス宣言の識別子の後の ": public IGameScene" というのが継承の構文だ。
public 継承によって、HelloScene は IGameScene として扱うことができる。
つまり SceneController にとっては、 IGameScene だけ扱えば済むということ。
これは何が嬉しいかと言えば、つまりはシーンが増えても SceneController を修正する必要がないってことだ。
超嬉しいね。
問題。
さて、実行してみれば分かると思うが(自分は試してない)、上の例は停止しない。
なぜかと言えば、 SceneController のスタック上にいつまでも HelloScene が居座り続けるからだ。
これをどうにかするためには、 play() を次のように書き換える。
int play() { std::cout << "Hello, World!" << std::endl; sc->unregist(this); return; }
この変更によって、 HelloWorld の表示の後、自分自身(this)が SceneController のスタック上から取り除かれる。
これで無限ループが発生することはなくなる。
次のステップ
さて、ココまでで無限ループのシーン(笑)と一度で正しく終了するシーンが書けたわけだ。
これを応用して五回 HelloWorld を表示(すなわち特定回数ループ)した後に終了するシーンが書ける。
これは宿題にしておこう!(飽きたとも言う)