Twilight's Call: Tower Defence> is a very basic Tower Defence game. You can place towers and when an enemy enters the Turrets range it fires a projectile to attack the enemy. When an enemy has incurred too much damage it will die and give the player more money to buy more turrets.
Each Turret has an area around itself and when an enemy enters or leaves its collision radius it triggers the turret to recalulate. The calculation is handled inside the enemy class. Enemy keeps track of how close it is to the current waypoint based on distance and how much distance is there between every other waypoint.
// returns the full distance from start to end
float AEnemy_Base::CalculateDistanceFromRemainingToEnd()
{
TArray TempWaypoints = Waypoints;
float TempDistance = 0;
// if there is less then two checkpoints remaining then we will return 0
if(!TempWaypoints.IsValidIndex(0) ||!TempWaypoints.IsValidIndex(1) )
{
return 0;
}
//Loop through each of the waypoints but remove one since we are incrementing above the List
for(int i = 0; i < TempWaypoints.Num() - 1;i++)
{
if(TempWaypoints.IsValidIndex(i + 1))
{
//Calculating the Distance Between the current waypoint and the next
TempDistance += FVector::Dist(TempWaypoints[i], TempWaypoints[i + 1]);
}
}
return TempDistance;
}
----------------------------------------------------------------------------------------------------
//Used when we have reached the current checkpoint and we are asking for the next one
void AEnemy_Base::GoToNextWaypoint()
{
//If there are no waypoints left the enemy has gotten to the goal
if(Waypoints.Num() == 0)
{
EnemyGotToGoal();
return;
}
//Calculating the distance between all the waypoints remaining
DistanceInAllRemainingWaypoints = CalculateDistanceFromRemainingToEnd();
//Attaching waypoint
CurrentWaypoint = Waypoints[0];
Waypoints.RemoveAt(0);
}
-----------------------------------------------------------------------------------------------
// Called in update
public void AEnemy_Base::MoveToWaypoint(float aDeltaTime)
{
DistanceToCurrentWaypoint = FVector::Dist(GetActorLocation(), GoToWaypoint);
CurrentDistanceRemaining = DistanceToCurrentWaypoint + DistanceInAllRemainingWaypoints;
}
-----------------------------------------------------------------------------------------------
// Inside the Turret, This is called every time someone enters or leaves the collision radius
void ATurret::CalculateClosestEnemy()
{
//If there is no enemy in range then exit the function
if(!EnemyInRange.IsValidIndex(0))
{
return;
}
//Setting the Default starting enemy for comparison
AEnemy_Base* EnemyTemp = Cast(EnemyInRange[0]);
//If there is more then one enemy do the calculations
if(EnemyInRange.Num() > 1)
{
for (int i = 0; i < EnemyInRange.Num(); i++)
{
AEnemy_Base* IterativeEnemy = Cast(EnemyInRange[i]);
//If the Waypoints are not initialize then continue the loop
if(IterativeEnemy->WaypointsAreSet == false)
{
continue;
}
//Getting the absolute value of the distances
float EnemyA = abs(IterativeEnemy->DistanceLeftInLevel);
float EnemyB = abs(EnemyTemp->DistanceLeftInLevel);
//Safety Check that if both values are 0 then something wrong is happening
if(EnemyA == 0 || EnemyB == 0 )
{
continue;
}
//Direct comparison between the two values the shortest distance will be swapped
if(EnemyA < EnemyB )
{
EnemyTemp = IterativeEnemy;
}
}
}
// The enemy that is furthest ahead will be selected.
EnemyToAttack = EnemyTemp;
//Adding the enemy to a delegate that gets called when the enemy is killed
EnemyToAttack->EnemyDeathEvent.AddDynamic(this, &ATurret::EnemyWasKilled);
}