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

第7回:敵vsプレイヤー(3)


企業サイトや人気サイトの運用実績多数!月額1,500円の高スペックレンタルサーバーヘテムル

プレイヤーと敵の衝突を判定


 敵とプレイヤーが衝突したときは、プレイヤーと敵の破壊処理をともにおこないます。衝突判定においては、CEnemy::Exec()が呼ばれるたびにプレイヤーがどこにいるかを調べることになるため、プレイヤークラスのポインタをCEnemyBase::Init()で読み取っておくことにします。

EnemyBase.h
class CEnemyBase : public CCharactor
{
protected:
	CPlayer *player;	// プレイヤークラスのポインタを追加

	int hardness;
	virtual void Init();
	public:
	virtual void Damaged();
};

EnemyBase.cpp
void CEnemyBase::Init()
{
	player = (CPlayer*)FindItemBox("player");
}


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

 プレイヤーが敵に衝突された際の破壊処理をCPlayerクラスに追加します。今回行うプログラム手法(CEnemyBaseクラス内で常にCPlayerクラスへのポインタを監視する)では、CPlayerクラスを削除してしまうとCPlayerへの参照が見つからず、プログラムエラーになってしまいます。そのため、CPlayerクラス内にdestroyedフラグを用意しておき、このフラグがオンである(つまりプレイヤーが破壊された)場合は、CPlayer::Exec()での処理を一切行わないようにすることで、この問題を回避しています。

Player.h
class CPlayer : public CCharactor
{
	/* 省略 */
private:
	bool destroyed;
public:
	void Destroy();
}

Player.cpp
#include "Explosion.h"

CPlayer::CPlayer()
{
	/* 省略 */

	destroyed = false;
}

void CPlayer::Exec()
{
	// 関数の先頭に追加
	if(destroyed == true) return;
	
	/* 省略 */
}

void CPlayer::Destroy()
{
	destroyed = true;

	// 爆発クラスの追加
	AppendObject(new CExplosion(x, y), EXPLOSION_PRIORITY, true);
}


企業サイトや人気サイトの運用実績多数!月額1,500円の高スペックレンタルサーバーヘテムル

 続いてCEnemyBaseの派生クラス(CEnemy1)のExec()において、プレイヤーとの衝突処理を行います。

Enemy1.cpp
void CEnemy1::Exec()
{
	/* 省略 */

	sprite.Draw(x, y);

	if(player->HitTest(this)){
		player->Destroy();
		this->Damaged();
	}
}

 これがプログラムの実行例です。