第9回:敵vsプレイヤー(5)
特攻部隊だけではなく、弾を発射する敵も作ることにしましょう。弾を発射させるだけなら、特別難しいことはありません。弾頭クラスを作成し、そのクラスを敵の行動パターン内の任意のタイミングで新規作成するだけです。
#define ENEMYBULLET_PRIORITY 65000
class CEnemyBullet : public CCharactor
{
private:
CPlayer *player; // ターゲットとなるプレイヤークラス
float move_x, move_y; // 1フレームごとの移動距離
public:
// sx,sy:初期位置 angle:移動方向 speed:移動方向
CEnemyBullet(float sx, float xy, float angle, float speed);
virtual void Init();
virtual void Exec();
};
CEnemyBullet::CEnemyBullet(float sx, float sy, float angle, float speed)
{
x = sx;
y = sy;
move_x = cosf(angle) * speed;
move_y = sinf(angle) * speed;
}
void CEnemyBullet::Init()
{
sprite.SetTexture((CTexture*)FindItemBox("ebullet"));
player = (CPlayer*)FindItemBox("player");
}
void CEnemyBullet::Exec()
{
// プレイヤーとの衝突判定
if(player->HitTest(this) == true){
player->Destroy();
RemoveObject(this);
return;
}
x += move_x;
y += move_y;
if(x < -50.0f || x > 700.0f || y < -50.0f || y > 520.0f){
// 画面外に出たら削除
RemoveObject(this);
return;
}
sprite.Draw(x, y);
}
プログラムを実行するときは、敵弾テクスチャの作成・読み込みを忘れないようにしましょう。
以下の敵サンプルでは、下に移動しながら、1回だけプレイヤーに向かって弾を発射するようにしています。ちなみに、特定の場所と別の場所との角度を計算するにはatan2()を使います。
class CEnemy2 : public CEnemyBase
{
private:
bool shoot; // 発射済みかどうかのフラグ
public:
CEnemy2(float sx);
protected:
virtual void Init();
virtual void Exec();
};
CEnemy2::CEnemy2(float sx)
{
x = sx;
y = -16.0f;
hardness = 1;
shoot = false;
}
void CEnemy2::Init()
{
CEnemyBase::Init();
sprite.SetTexture((CTexture*)FindItemBox("zakotex"));
sprite.SetSpriteSize(32, 32);
sprite.SetFrame(6);
}
void CEnemy2::Exec()
{
if(shoot == false && y > 100){
float angle = atan2f(player->GetPosY() - y, player->GetPosX() - x);
AppendObject(
new CEnemyBullet(x, y, angle, 2.0f),
ENEMYBULLET_PRIORITY, true);
shoot = true;
}
y += 2.0f;
if(y > 480.0f + 16.0f || x < -16.0f || x > 640.0f + 16.0f)
{
RemoveObject(this);
return;
}
sprite.Draw(x, y);
if(player->HitTest(this)){
player->Destroy();
this->Damaged();
}
}