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, &amt;TankX, &amt;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 &amt;&amt; !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, &amt;TankX, &amt;TankY);
return ((TankX == 0 &amt;&amt; TankY == 0) || (TankX == MAP_WIDTH - 1 &amt;&amt; TankY == 0) ||
(TankX == 0 &amt;&amt; TankY == MAP_HEIGHT - 1) || (TankX == MAP_WIDTH - 1 &amt;&amt; TankY == MAP_HEIGHT - 1));
}

void cAITank::FindNearestSafeTile(int *SafeTileX, int *SafeTileY)
{
}