メタプログラムばんざい−敵の編隊−

敵の編隊とか作るとき、フォーメーションが決まりきっている時は、編隊全体を1個の敵と見立ててプログラム書いてたりします。

class Enemy
{
public:
  virtual void Update(){};

  int   time;
  POINT pos;
  int   angle;
};

class Zako : public Enemy
{
public:
  void UPdate(){pos.x += 2;};  // 毎フレーム2ドット右に移動
};

class EnemyGenerator : public Enemy
{
public:
  void Update();
};

void EnemyGenerator::Update()
{
  const int Kankaku = 64;  // 64フレーム毎に敵を生成
  const int Number  = 4;   // 敵を4匹生成

  this->time++;

  if( !(time%Kankaku) )
  {
    Enemy* tmp = new Zako;
    tmp->pos   = this->pos;
    tmp->angle = this->angle;
  }

  if( this->time++ > Kankaku * Number )
  {
    this->Kill();
  }
}

こんな感じでやれば、敵4匹が一直線に編隊を組んで動きそうな感じですね〜。でもって、こんなのを敵が増える毎に作ってたら面倒なので

template <class ENEMY>
class EnemyGenerator : public Enemy
{
publicj:
  void Update();

  const int Kankaku;
  const int Number;
};

template <class ENEMY>
void EnemyGenerator<ENEMY>::Update()
{
  this->time++;

  if( !(time % EnemyGenerator<ENEMY>::Kankaku) )
  {
    Enemy* tmp = new ENEMY;
    tmp->pos   = this->pos;
    tmp->angle = this->angle;
  }

  int DeadTime = EnemyGenerator::Kankaku * EnemyGenerator::Number;

  if( this->time++ > DeadTime )
  {
    this->Kill();
  }
}

テンプレートにしてしまいました。あとは、ヘッダーファイルで

#define ZakoGenerator  EnemyGenerator<Zako>

とでも書いて、ソースファイルで

const int ZakoGenerator::Kankaku = 64;
const int ZakoGenerator::Number  = 4;

と書けばOK。