Improve Game Over Screen
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -48,6 +48,7 @@ public:
|
||||
void RestartGame();
|
||||
int32 GetKillCount() const { return KillCount; }
|
||||
float GetRemainingTime() const { return RemainingTime; }
|
||||
float GetGameDuration() const { return GameDuration; }
|
||||
bool IsGameOver() const { return bIsGameOver; }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -10,6 +10,7 @@ ASpaceShooterHUD::ASpaceShooterHUD()
|
||||
// Find and set the default font
|
||||
static ConstructorHelpers::FObjectFinder<UFont> FontObj(TEXT("/Engine/EngineFonts/RobotoDistanceField"));
|
||||
TextFont = FontObj.Object;
|
||||
GameOverStartTime = 0.0f;
|
||||
}
|
||||
|
||||
ASpaceshipPawn* ASpaceShooterHUD::GetPlayerPawn() const
|
||||
@@ -112,39 +113,113 @@ void ASpaceShooterHUD::DrawGameplayHUD()
|
||||
DrawStatusBars();
|
||||
}
|
||||
|
||||
void ASpaceShooterHUD::DrawGameOverBackground()
|
||||
{
|
||||
if (!Canvas) return;
|
||||
|
||||
// Draw a semi-transparent black background
|
||||
FCanvasBoxItem BoxItem(FVector2D(0, 0), FVector2D(Canvas->SizeX, Canvas->SizeY));
|
||||
BoxItem.SetColor(FLinearColor(0.0f, 0.0f, 0.0f, 0.7f));
|
||||
Canvas->DrawItem(BoxItem);
|
||||
}
|
||||
|
||||
void ASpaceShooterHUD::DrawGameOverText(const FString& Text, const FVector2D& Position, const FLinearColor& Color, float Scale)
|
||||
{
|
||||
if (!Canvas || !TextFont) return;
|
||||
|
||||
float TextWidth, TextHeight;
|
||||
GetTextSize(Text, TextWidth, TextHeight, TextFont, Scale);
|
||||
|
||||
// Draw text shadow
|
||||
DrawText(Text, FLinearColor(0.0f, 0.0f, 0.0f, Color.A * 0.5f),
|
||||
Position.X + 3.0f, Position.Y + 3.0f, TextFont, Scale);
|
||||
|
||||
// Draw main text
|
||||
DrawText(Text, Color, Position.X, Position.Y, TextFont, Scale);
|
||||
}
|
||||
|
||||
void ASpaceShooterHUD::DrawGameOverScreen()
|
||||
{
|
||||
ASpaceShooterGameMode* GameMode = GetGameMode();
|
||||
if (!GameMode) return;
|
||||
if (!GameMode || !Canvas) return;
|
||||
|
||||
// Initialize GameOverStartTime if needed
|
||||
if (GameOverStartTime == 0.0f)
|
||||
{
|
||||
GameOverStartTime = GetWorld()->GetTimeSeconds();
|
||||
}
|
||||
|
||||
// Draw darkened background
|
||||
DrawGameOverBackground();
|
||||
|
||||
// Get canvas dimensions
|
||||
const FVector2D ViewportSize(Canvas->SizeX, Canvas->SizeY);
|
||||
const float CurrentTime = GetWorld()->GetTimeSeconds();
|
||||
const float TimeSinceGameOver = CurrentTime - GameOverStartTime;
|
||||
|
||||
// Calculate pulsating alpha for "GAME OVER" text
|
||||
float PulsatingAlpha = FMath::Lerp(PulsateMinAlpha, PulsateMaxAlpha,
|
||||
(FMath::Sin(TimeSinceGameOver * PulsateSpeed) + 1.0f) * 0.5f);
|
||||
|
||||
// Calculate vertical positions
|
||||
float CenterY = ViewportSize.Y * 0.4f; // Slightly above center
|
||||
float Spacing = 60.0f * GameOverScale;
|
||||
|
||||
// Draw "GAME OVER" with pulsating effect
|
||||
FLinearColor PulsatingColor = GameOverTextColor;
|
||||
PulsatingColor.A = PulsatingAlpha;
|
||||
|
||||
// Draw game over text
|
||||
FString GameOverText = TEXT("GAME OVER");
|
||||
float TextWidth, TextHeight;
|
||||
GetTextSize(GameOverText, TextWidth, TextHeight, TextFont);
|
||||
GetTextSize(GameOverText, TextWidth, TextHeight, TextFont, GameOverScale);
|
||||
|
||||
DrawText(GameOverText, FLinearColor::Red,
|
||||
ViewportSize.X / 2 - TextWidth / 2,
|
||||
ViewportSize.Y / 2 - TextHeight / 2,
|
||||
TextFont, 2.0f);
|
||||
DrawGameOverText(GameOverText,
|
||||
FVector2D((ViewportSize.X - TextWidth) * 0.5f, CenterY),
|
||||
PulsatingColor,
|
||||
GameOverScale);
|
||||
|
||||
// Draw final score
|
||||
FString ScoreText = FString::Printf(TEXT("Final Kill Count: %d"), GameMode->GetKillCount());
|
||||
GetTextSize(ScoreText, TextWidth, TextHeight, TextFont);
|
||||
DrawText(ScoreText, FLinearColor::White,
|
||||
ViewportSize.X / 2 - TextWidth / 2,
|
||||
ViewportSize.Y / 2 + TextHeight * 2,
|
||||
TextFont);
|
||||
// Draw stats with scaling animations
|
||||
const float StatsScale = 1.5f;
|
||||
float StatsY = CenterY + Spacing;
|
||||
|
||||
// Draw restart instructions
|
||||
// Time Survived
|
||||
int32 TotalSeconds = FMath::RoundToInt(GameMode->GetGameDuration() - GameMode->GetRemainingTime());
|
||||
int32 Minutes = TotalSeconds / 60;
|
||||
int32 Seconds = TotalSeconds % 60;
|
||||
FString TimeText = FString::Printf(TEXT("Time Survived: %02d:%02d"), Minutes, Seconds);
|
||||
GetTextSize(TimeText, TextWidth, TextHeight, TextFont, StatsScale);
|
||||
DrawGameOverText(TimeText,
|
||||
FVector2D((ViewportSize.X - TextWidth) * 0.5f, StatsY),
|
||||
StatsTextColor,
|
||||
StatsScale);
|
||||
|
||||
// Kill Count
|
||||
StatsY += Spacing * 0.7f;
|
||||
FString KillText = FString::Printf(TEXT("Enemies Destroyed: %d"), GameMode->GetKillCount());
|
||||
GetTextSize(KillText, TextWidth, TextHeight, TextFont, StatsScale);
|
||||
DrawGameOverText(KillText,
|
||||
FVector2D((ViewportSize.X - TextWidth) * 0.5f, StatsY),
|
||||
StatsTextColor,
|
||||
StatsScale);
|
||||
|
||||
// Calculate final score based on time and kills
|
||||
int32 FinalScore = GameMode->GetKillCount() * 100 + TotalSeconds * 10;
|
||||
StatsY += Spacing * 0.7f;
|
||||
FString ScoreText = FString::Printf(TEXT("Final Score: %d"), FinalScore);
|
||||
GetTextSize(ScoreText, TextWidth, TextHeight, TextFont, StatsScale);
|
||||
DrawGameOverText(ScoreText,
|
||||
FVector2D((ViewportSize.X - TextWidth) * 0.5f, StatsY),
|
||||
StatsTextColor,
|
||||
StatsScale);
|
||||
|
||||
// Draw restart text with bounce effect
|
||||
float BounceOffset = FMath::Sin(TimeSinceGameOver * 3.0f) * 5.0f;
|
||||
StatsY += Spacing * 1.2f;
|
||||
FString RestartText = TEXT("Press R to Restart");
|
||||
GetTextSize(RestartText, TextWidth, TextHeight, TextFont);
|
||||
DrawText(RestartText, FLinearColor::Yellow,
|
||||
ViewportSize.X / 2 - TextWidth / 2,
|
||||
ViewportSize.Y / 2 + TextHeight * 4,
|
||||
TextFont);
|
||||
GetTextSize(RestartText, TextWidth, TextHeight, TextFont, StatsScale);
|
||||
DrawGameOverText(RestartText,
|
||||
FVector2D((ViewportSize.X - TextWidth) * 0.5f, StatsY + BounceOffset),
|
||||
RestartTextColor,
|
||||
StatsScale);
|
||||
}
|
||||
|
||||
ASpaceShooterGameMode* ASpaceShooterHUD::GetGameMode() const
|
||||
|
||||
@@ -36,10 +36,36 @@ protected:
|
||||
UPROPERTY(EditAnywhere, Category = "HUD|Bars")
|
||||
FLinearColor BackgroundBarColor = FLinearColor(0.0f, 0.0f, 0.0f, 0.5f); // Semi-transparent black
|
||||
|
||||
// Game Over Screen Configuration
|
||||
UPROPERTY(EditAnywhere, Category = "HUD|GameOver")
|
||||
float GameOverScale = 3.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "HUD|GameOver")
|
||||
FLinearColor GameOverTextColor = FLinearColor(1.0f, 0.2f, 0.2f, 1.0f); // Bright red
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "HUD|GameOver")
|
||||
FLinearColor StatsTextColor = FLinearColor(0.9f, 0.9f, 0.9f, 1.0f); // Off-white
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "HUD|GameOver")
|
||||
FLinearColor RestartTextColor = FLinearColor(1.0f, 0.843f, 0.0f, 1.0f); // Gold
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "HUD|GameOver")
|
||||
float PulsateSpeed = 2.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "HUD|GameOver")
|
||||
float PulsateMinAlpha = 0.7f;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "HUD|GameOver")
|
||||
float PulsateMaxAlpha = 1.0f;
|
||||
|
||||
private:
|
||||
void DrawGameplayHUD();
|
||||
void DrawGameOverScreen();
|
||||
void DrawStatusBars();
|
||||
class ASpaceShooterGameMode* GetGameMode() const;
|
||||
class ASpaceshipPawn* GetPlayerPawn() const;
|
||||
|
||||
float GameOverStartTime;
|
||||
void DrawGameOverBackground();
|
||||
void DrawGameOverText(const FString& Text, const FVector2D& Position, const FLinearColor& Color, float Scale = 1.0f);
|
||||
};
|
||||
@@ -586,10 +586,6 @@ void ASpaceshipPawn::Die()
|
||||
DisableInput(PC);
|
||||
}
|
||||
|
||||
// You could either restart the level after a delay or show a game over screen here
|
||||
// For example:
|
||||
// GetWorldTimerManager().SetTimer(RestartTimerHandle, this, &ASpaceshipPawn::RestartLevel, 3.0f, false);
|
||||
|
||||
// For now, just log the death
|
||||
if (GEngine)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user