17:複数のオブジェクトを扱うテクニック
結論から言うと、タスクリストにExec()の実装していないオブジェクトを追加し、必要に応じてこのリストから呼び出せばいいことになります。と、いうことで、まずはリストの中から特定のオブジェクトを参照するための関数を作成することにしましょう。タスク追加時に用いた文字列と検索に用いるキー文字列と完全一致したならば、目的のCGameObjectと判断して、そのオブジェクトを返します。見つからなければNULL値を返すようにしています。/* 省略 */
class CGameObject
{
/* 省略 */
public:
/* 省略 */
CGameObject* FindObject(char *name);
protected:
/* 省略 */
};
CGameObject* CGameObject::FindObject(char *name)
{
list<ListData>::iterator i;
for(i = objectlist.begin(); i != objectlist.end(); i++){
if(strcmp((*i).name, name) == 0) return (*i).gameobj;
}
return NULL;
}
それでは、初期化処理専用のクラス「CDxFontTestStart」と、動作処理専用のクラス「CMoveFont」を作成してみることにしましょう。
一方、タスク処理リストからExec()コマンドが呼び出されるたびに、座標は上下方向にm分だけ移動し、上下の端にたどり着いたら方向転換が行われます。今回はサンプルプログラムなので、乱数生成関数rand()の乱数は常に一定です。必要に応じてプログラムのどこかにsrand()関数を追加して、生成法則を不定にするようにするとよいでしょう。
初期化専用クラスCDxFontTestStartでは、ID3DXFontを格納したクラスをリストに追加し、先ほど解説したCMoveFontを横方向に並べるだけ並べています。
#include "..\DxFont.h"
class CDxFontTestStart : public CGameObject
{
protected:
void Init();
};
class CMoveFont : public CGameObject
{
public:
void SetStartState(int pos_x, int pos_y, int speed);
private:
int x, y, m;
CDxFont *pFont;
protected:
void Init();
void Exec();
};
#include "DxFontTest.h"
void CDxFontTestStart::Init()
{
// フォントオブジェクトをリストに追加
AppendObject(new CDxFont(), -1, "font", true);
// 30ピクセル間隔で、移動するフォントのオブジェクトを配置
CMoveFont *movefont;
for(int x = 0; x < 640; x += 30){
movefont = new CMoveFont();
movefont->SetStartState(x, rand() % (480 - 16), rand() % 4 + 1);
AppendObject(movefont, 1000 + x, true);
}
// 自分自身は必要なくなったので消去
RemoveObject(this);
}
void CMoveFont::SetStartState(int pos_x, int pos_y, int speed)
{
x = pos_x;
y = pos_y;
m = speed;
}
void CMoveFont::Init()
{
// オブジェクトデータを参照として格納
pFont = (CDxFont*)FindObject("font");
}
void CMoveFont::Exec()
{
if(pFont){
// 上下の端についたら方向転換
if(y < 0 || y > 480 - 16) m = -m;
y += m;
pFont->Draw(_T("Text"), x, y);
}
}