Initial HUD implementation and timer + game over
This commit is contained in:
153
Source/MyProject3/SpaceShooterHUD.cpp
Normal file
153
Source/MyProject3/SpaceShooterHUD.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
#include "SpaceShooterHUD.h"
|
||||
#include "SpaceShooterGameMode.h"
|
||||
#include "Engine/Canvas.h"
|
||||
#include "Engine/Font.h"
|
||||
#include "SpaceshipPawn.h"
|
||||
#include "UObject/ConstructorHelpers.h"
|
||||
|
||||
ASpaceShooterHUD::ASpaceShooterHUD()
|
||||
{
|
||||
// Find and set the default font
|
||||
static ConstructorHelpers::FObjectFinder<UFont> FontObj(TEXT("/Engine/EngineFonts/RobotoDistanceField"));
|
||||
TextFont = FontObj.Object;
|
||||
}
|
||||
|
||||
ASpaceshipPawn* ASpaceShooterHUD::GetPlayerPawn() const
|
||||
{
|
||||
APlayerController* PC = GetWorld()->GetFirstPlayerController();
|
||||
if (PC)
|
||||
{
|
||||
return Cast<ASpaceshipPawn>(PC->GetPawn());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Add this new function for drawing the bars
|
||||
void ASpaceShooterHUD::DrawStatusBars()
|
||||
{
|
||||
if (!Canvas) return;
|
||||
|
||||
ASpaceshipPawn* PlayerPawn = GetPlayerPawn();
|
||||
if (!PlayerPawn) return;
|
||||
|
||||
// Get the canvas size
|
||||
const float ScreenWidth = Canvas->SizeX;
|
||||
const float ScreenHeight = Canvas->SizeY;
|
||||
|
||||
// Calculate positions for the bars (top right corner)
|
||||
float StartX = ScreenWidth - BarWidth - BarPadding;
|
||||
float HealthY = BarPadding;
|
||||
float ShieldY = HealthY + BarHeight + BarPadding;
|
||||
|
||||
// Get current health and shield values
|
||||
float HealthPercent = PlayerPawn->GetCurrentHealth() / PlayerPawn->GetMaxHealth();
|
||||
float ShieldPercent = PlayerPawn->GetCurrentShield() / PlayerPawn->GetMaxShield();
|
||||
|
||||
// Clamp values between 0 and 1
|
||||
HealthPercent = FMath::Clamp(HealthPercent, 0.0f, 1.0f);
|
||||
ShieldPercent = FMath::Clamp(ShieldPercent, 0.0f, 1.0f);
|
||||
|
||||
// Draw health bar background
|
||||
FCanvasBoxItem HealthBG(FVector2D(StartX, HealthY), FVector2D(BarWidth, BarHeight));
|
||||
HealthBG.SetColor(BackgroundBarColor);
|
||||
Canvas->DrawItem(HealthBG);
|
||||
|
||||
// Draw health bar fill
|
||||
FCanvasBoxItem HealthFill(FVector2D(StartX, HealthY), FVector2D(BarWidth * HealthPercent, BarHeight));
|
||||
HealthFill.SetColor(HealthBarColor);
|
||||
Canvas->DrawItem(HealthFill);
|
||||
|
||||
// Draw shield bar background
|
||||
FCanvasBoxItem ShieldBG(FVector2D(StartX, ShieldY), FVector2D(BarWidth, BarHeight));
|
||||
ShieldBG.SetColor(BackgroundBarColor);
|
||||
Canvas->DrawItem(ShieldBG);
|
||||
|
||||
// Draw shield bar fill
|
||||
FCanvasBoxItem ShieldFill(FVector2D(StartX, ShieldY), FVector2D(BarWidth * ShieldPercent, BarHeight));
|
||||
ShieldFill.SetColor(ShieldBarColor);
|
||||
Canvas->DrawItem(ShieldFill);
|
||||
|
||||
// Draw text labels
|
||||
FString HealthText = FString::Printf(TEXT("Health: %.0f%%"), HealthPercent * 100);
|
||||
FString ShieldText = FString::Printf(TEXT("Shield: %.0f%%"), ShieldPercent * 100);
|
||||
|
||||
// Draw text over the bars
|
||||
DrawText(HealthText, FLinearColor::White, StartX + 5, HealthY + 2, TextFont, 0.8f);
|
||||
DrawText(ShieldText, FLinearColor::White, StartX + 5, ShieldY + 2, TextFont, 0.8f);
|
||||
}
|
||||
|
||||
void ASpaceShooterHUD::DrawHUD()
|
||||
{
|
||||
Super::DrawHUD();
|
||||
|
||||
ASpaceShooterGameMode* GameMode = GetGameMode();
|
||||
if (!GameMode) return;
|
||||
|
||||
if (!GameMode->IsGameOver())
|
||||
{
|
||||
DrawGameplayHUD();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGameOverScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void ASpaceShooterHUD::DrawGameplayHUD()
|
||||
{
|
||||
ASpaceShooterGameMode* GameMode = GetGameMode();
|
||||
if (!GameMode) return;
|
||||
|
||||
// Draw timer
|
||||
int32 Minutes = FMath::FloorToInt(GameMode->GetRemainingTime() / 60.0f);
|
||||
int32 Seconds = FMath::FloorToInt(FMath::Fmod(GameMode->GetRemainingTime(), 60.0f));
|
||||
FString TimeString = FString::Printf(TEXT("Time: %02d:%02d"), Minutes, Seconds);
|
||||
DrawText(TimeString, FLinearColor::White, 50, 50, TextFont);
|
||||
|
||||
// Draw kill count
|
||||
FString KillString = FString::Printf(TEXT("Kills: %d"), GameMode->GetKillCount());
|
||||
DrawText(KillString, FLinearColor::White, 50, 100, TextFont);
|
||||
|
||||
// Draw status bars
|
||||
DrawStatusBars();
|
||||
}
|
||||
|
||||
void ASpaceShooterHUD::DrawGameOverScreen()
|
||||
{
|
||||
ASpaceShooterGameMode* GameMode = GetGameMode();
|
||||
if (!GameMode) return;
|
||||
|
||||
// Get canvas dimensions
|
||||
const FVector2D ViewportSize(Canvas->SizeX, Canvas->SizeY);
|
||||
|
||||
// Draw game over text
|
||||
FString GameOverText = TEXT("GAME OVER");
|
||||
float TextWidth, TextHeight;
|
||||
GetTextSize(GameOverText, TextWidth, TextHeight, TextFont);
|
||||
|
||||
DrawText(GameOverText, FLinearColor::Red,
|
||||
ViewportSize.X / 2 - TextWidth / 2,
|
||||
ViewportSize.Y / 2 - TextHeight / 2,
|
||||
TextFont, 2.0f);
|
||||
|
||||
// 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 restart instructions
|
||||
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);
|
||||
}
|
||||
|
||||
ASpaceShooterGameMode* ASpaceShooterHUD::GetGameMode() const
|
||||
{
|
||||
return Cast<ASpaceShooterGameMode>(GetWorld()->GetAuthGameMode());
|
||||
}
|
||||
Reference in New Issue
Block a user