www.pudn.com > sxdl.zip > cAITank.cpp


#include "cAITank.h" 
#include "cBoomBastic.h" 
#include "bbUtil.h" 
 
cAITank::cAITank(CBasicSprite *TankSprites[4], int TankX, int TankY, int TankID) : 
	cTank(TankSprites, TankX, TankY, TankID, 0) 
{ 
} 
 
bool cAITank::OnAnimate(float ElapsedTime, float AbsoluteTime) 
{ 
	int TankX, TankY; 
	g_BoomBastic.Tilemap->ConvertWorldToMap(Position, &TankX, &TankY); 
	//Si le tank est sur une tile qui risque d'etre en feu, on cherche une tile sans danger 
	if (WillBeInFire(TankX, TankY)) 
	{ 
		 
		cTank::OnAnimate(ElapsedTime, AbsoluteTime); 
	} 
	//Sinon, on se dirige vers le tank le plus proche 
	else 
	{ 
		Vector3 OldPosition = Position; 
		 
		//On cherche le tank le plus proche 
		cTank *NearestTank = NULL; 
		float CurrentDistance = 10000.0f; 
		int i; 
		for (i = 0; i < 4; i++) 
		{ 
			if (i == m_TankID) 
				continue; 
			 
			Vector3 TankToTank = g_BoomBastic.Tanks[i]->Position - Position; 
			float Distance = GetVector3Norm(TankToTank); 
			if (Distance < CurrentDistance) 
			{ 
				CurrentDistance = Distance; 
				NearestTank = g_BoomBastic.Tanks[i]; 
			} 
		} 
		 
		//Si on ne l'a pas trouve, on s'arrete 
		if (!NearestTank) 
			return true; 
		 
		//Sinon, on se dirige betement vers le tank le plus proche 
		Vector3 ThisTankToNeareastTank = NearestTank->Position - Position; 
		if (ThisTankToNeareastTank.x > 0.0f) 
			MoveTank(RIGHT_DIRECTION); 
		else if (ThisTankToNeareastTank.x < 0.0f) 
			MoveTank(LEFT_DIRECTION); 
		 
		if (ThisTankToNeareastTank.y > 0.0f) 
			MoveTank(UP_DIRECTION); 
		else if (ThisTankToNeareastTank.y < 0.0f) 
			MoveTank(DOWN_DIRECTION); 
		 
		//On calcule la nouvelle position du tank 
		cTank::OnAnimate(ElapsedTime, AbsoluteTime); 
		 
		//Si le deplacement effectue est nul, le tank est bloqué et il pose alors une bombe 
		//(On verifie egalement que le tank n'est pas dans un coin de la map, pour eviter qu'il se fasse exploser des le debut) 
		Vector3 FinalMove = Position - OldPosition; 
		if (GetVector3Norm(FinalMove) == 0.0f && !IsInACorner()) 
			DropBomb(); 
	} 
	 
	return true; 
} 
 
bool cAITank::WillBeInFire(int TileX, int TileY) 
{ 
	int i; 
	//Si une bombe ou une boule de feu est sur la rangee de la tile, on considere que la tile peut etre en feu 
	for (i = 0; i < MAP_WIDTH; i++) 
	{ 
		if (g_BoomBastic.Tilemap->LogicalMap(i, TileY) == LMAP_BOMB) 
			return true; 
	} 
	//Si une bombe ou une boule de feu est sur la colonne de la tile, on considere que la tile peut etre en feu 
	for (i = 0; i < MAP_WIDTH; i++) 
	{ 
		if (g_BoomBastic.Tilemap->LogicalMap(i, TileY) == LMAP_BOMB) 
			return true; 
	} 
	//Probleme: on ne prend pas en compte la portee de la bombe 
	 
	//Sinon la tile est sans danger	 
	return false; 
} 
 
bool cAITank::IsInACorner() 
{ 
	int TankX, TankY; 
	g_BoomBastic.Tilemap->ConvertWorldToMap(Position, &TankX, &TankY); 
	return ((TankX == 0 && TankY == 0) || (TankX == MAP_WIDTH - 1 && TankY == 0) ||  
		(TankX == 0 && TankY == MAP_HEIGHT - 1) || (TankX == MAP_WIDTH - 1 && TankY == MAP_HEIGHT - 1)); 
} 
 
void cAITank::FindNearestSafeTile(int *SafeTileX, int *SafeTileY) 
{ 
}