Implement enemy shooting and scale down for more arcade game feel

This commit is contained in:
2025-04-15 22:21:28 +05:30
parent ca23fd129e
commit e2e709bffd
14 changed files with 886 additions and 41 deletions

View File

@@ -156,15 +156,18 @@ void ASpaceShooterGameMode::SpawnEnemyWave()
// Create a line of enemies perpendicular to the direction
FVector2D PerpDirection(-EdgeDirection.Y, EdgeDirection.X);
// Spawn wave of enemies
// Spawn wave of enemies - increased distance from 2000 to MinimumSpawnDistance
for (int32 i = 0; i < WaveSize; i++)
{
FVector SpawnLocation;
SpawnLocation.X = PlayerLocation.X + (EdgeDirection.X * 2000.0f) +
FVector ProposedLocation;
ProposedLocation.X = PlayerLocation.X + (EdgeDirection.X * MinimumSpawnDistance) +
(PerpDirection.X * (i - WaveSize / 2) * FormationSpacing);
SpawnLocation.Y = PlayerLocation.Y + (EdgeDirection.Y * 2000.0f) +
ProposedLocation.Y = PlayerLocation.Y + (EdgeDirection.Y * MinimumSpawnDistance) +
(PerpDirection.Y * (i - WaveSize / 2) * FormationSpacing);
SpawnLocation.Z = PlayerLocation.Z;
ProposedLocation.Z = PlayerLocation.Z;
// Ensure the spawn location is far enough from the player
FVector SpawnLocation = EnsureMinimumSpawnDistance(ProposedLocation, PlayerLocation);
FRotator SpawnRotation = FRotator::ZeroRotator;
FActorSpawnParameters SpawnParams;
@@ -205,8 +208,8 @@ void ASpaceShooterGameMode::SpawnEnemyFormation()
float ApproachAngle = FMath::RandRange(0.0f, 2.0f * PI);
FVector2D ApproachDir(FMath::Cos(ApproachAngle), FMath::Sin(ApproachAngle));
// Base spawn position far from player
FVector BaseSpawnPos = PlayerLocation + FVector(ApproachDir.X, ApproachDir.Y, 0) * 2500.0f;
// Base spawn position far from player - increased from 2500 to MinimumSpawnDistance + 500
FVector BaseSpawnPos = PlayerLocation + FVector(ApproachDir.X, ApproachDir.Y, 0) * (MinimumSpawnDistance + 500.0f);
// Create formation positions
TArray<FVector> FormationPositions;
@@ -261,13 +264,16 @@ void ASpaceShooterGameMode::SpawnEnemyFormation()
// Spawn enemies at formation positions
for (const FVector& Position : FormationPositions)
{
// Ensure the spawn location is far enough from the player
FVector SpawnLocation = EnsureMinimumSpawnDistance(Position, PlayerLocation);
FRotator SpawnRotation = FRotator::ZeroRotator;
FActorSpawnParameters SpawnParams;
SpawnParams.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
AEnemySpaceship* NewEnemy = World->SpawnActor<AEnemySpaceship>(
EnemyClass, Position, SpawnRotation, SpawnParams);
EnemyClass, SpawnLocation, SpawnRotation, SpawnParams);
if (NewEnemy)
{
@@ -307,7 +313,11 @@ void ASpaceShooterGameMode::SpawnEnemyFlanking()
float OffsetAngle = Angle + FMath::RandRange(-0.3f, 0.3f);
FVector2D OffsetDir(FMath::Cos(OffsetAngle), FMath::Sin(OffsetAngle));
FVector SpawnLocation = PlayerLocation + FVector(OffsetDir.X, OffsetDir.Y, 0) * 2000.0f;
// Increased from 2000 to MinimumSpawnDistance
FVector ProposedLocation = PlayerLocation + FVector(OffsetDir.X, OffsetDir.Y, 0) * MinimumSpawnDistance;
// Ensure the spawn location is far enough from the player
FVector SpawnLocation = EnsureMinimumSpawnDistance(ProposedLocation, PlayerLocation);
FRotator SpawnRotation = FRotator::ZeroRotator;
FActorSpawnParameters SpawnParams;
@@ -339,30 +349,34 @@ FVector ASpaceShooterGameMode::GetScreenEdgeSpawnLocation()
FVector SpawnLocation;
float RandomPos;
// Increased margin to spawn farther from screen edges
float ExtendedMargin = ScreenSpawnMargin + 500.0f;
switch (Edge)
{
case 0: // Top edge
RandomPos = FMath::RandRange(ScreenBounds[0].X, ScreenBounds[1].X);
SpawnLocation = FVector(RandomPos, ScreenBounds[0].Y - ScreenSpawnMargin, PlayerLocation.Z);
SpawnLocation = FVector(RandomPos, ScreenBounds[0].Y - ExtendedMargin, PlayerLocation.Z);
break;
case 1: // Right edge
RandomPos = FMath::RandRange(ScreenBounds[0].Y, ScreenBounds[1].Y);
SpawnLocation = FVector(ScreenBounds[1].X + ScreenSpawnMargin, RandomPos, PlayerLocation.Z);
SpawnLocation = FVector(ScreenBounds[1].X + ExtendedMargin, RandomPos, PlayerLocation.Z);
break;
case 2: // Bottom edge
RandomPos = FMath::RandRange(ScreenBounds[0].X, ScreenBounds[1].X);
SpawnLocation = FVector(RandomPos, ScreenBounds[1].Y + ScreenSpawnMargin, PlayerLocation.Z);
SpawnLocation = FVector(RandomPos, ScreenBounds[1].Y + ExtendedMargin, PlayerLocation.Z);
break;
case 3: // Left edge
RandomPos = FMath::RandRange(ScreenBounds[0].Y, ScreenBounds[1].Y);
SpawnLocation = FVector(ScreenBounds[0].X - ScreenSpawnMargin, RandomPos, PlayerLocation.Z);
SpawnLocation = FVector(ScreenBounds[0].X - ExtendedMargin, RandomPos, PlayerLocation.Z);
break;
}
return SpawnLocation;
// Ensure the spawn location is far enough from the player
return EnsureMinimumSpawnDistance(SpawnLocation, PlayerLocation);
}
FVector ASpaceShooterGameMode::GetSpawnZoneLocation()
@@ -395,6 +409,7 @@ FVector ASpaceShooterGameMode::GetSpawnZoneLocation()
// Select a zone based on weight
float RandomWeight = FMath::RandRange(0.0f, TotalWeight);
float WeightSum = 0.0f;
FVector PlayerLocation = GetPlayerLocation();
for (const FSpawnZone& Zone : ActiveZones)
{
@@ -411,7 +426,10 @@ FVector ASpaceShooterGameMode::GetSpawnZoneLocation()
0.0f
);
return Zone.Location + SpawnOffset;
FVector ProposedLocation = Zone.Location + SpawnOffset;
// Ensure the spawn location is far enough from the player
return EnsureMinimumSpawnDistance(ProposedLocation, PlayerLocation);
}
}
@@ -504,4 +522,22 @@ void ASpaceShooterGameMode::RotateTowardsPlayer(AEnemySpaceship* Enemy, const FV
// Set the enemy's rotation
Enemy->SetActorRotation(NewRotation);
}
// New function to ensure enemies spawn at least MinimumSpawnDistance away from player
FVector ASpaceShooterGameMode::EnsureMinimumSpawnDistance(const FVector& ProposedLocation, const FVector& PlayerLocation)
{
FVector Direction = ProposedLocation - PlayerLocation;
Direction.Z = 0; // Keep on the same Z plane as the player
float CurrentDistance = Direction.Size();
// If already far enough, return the proposed location
if (CurrentDistance >= MinimumSpawnDistance)
{
return ProposedLocation;
}
// Otherwise, extend the vector to meet the minimum distance
Direction.Normalize();
return PlayerLocation + Direction * MinimumSpawnDistance;
}