クラスまみれのゲームプログラミング入門

第9回:敵vsプレイヤー(5)

 特攻部隊だけではなく、弾を発射する敵も作ることにしましょう。弾を発射させるだけなら、特別難しいことはありません。弾頭クラスを作成し、そのクラスを敵の行動パターン内の任意のタイミングで新規作成するだけです。

EnemyBase.h
#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();
};

EnemyBase.cpp
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);
}

 プログラムを実行するときは、敵弾テクスチャの作成・読み込みを忘れないようにしましょう。


ebullet.png


激安アウトレットはこちら!安心のメーカー直販店【エレコム】

 以下の敵サンプルでは、下に移動しながら、1回だけプレイヤーに向かって弾を発射するようにしています。ちなみに、特定の場所と別の場所との角度を計算するにはatan2()を使います。

Enemy.h
class CEnemy2 : public CEnemyBase
{
private:
	bool shoot; // 発射済みかどうかのフラグ
public:
	CEnemy2(float sx);
protected:
	virtual void Init();
	virtual void Exec();
};

Enemy.cpp
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();
	}
}