render: replace game over screen with end screen; show stats breakdown

The game over logic is now consolidated as there are two possible
scenarios: victory or death. The end-screen rendering has thus been
consolidated to display victory (gold YOU ESCAPED) or death (red GAME OVER)
with a stats box. 

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Iecf71ecde4097a41bd074f9123c8c4c76a6a6964
This commit is contained in:
raf 2026-04-08 10:26:52 +03:00
commit 436083f606
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
2 changed files with 92 additions and 11 deletions

View file

@ -351,19 +351,99 @@ void render_floating_texts(FloatingText *texts, int count, int shake_x, int shak
}
}
void render_game_over(void) {
void render_end_screen(int is_victory, int kills, int items, int damage_dealt, int damage_taken, int crits,
int times_hit, int potions, int floors, int turns, int score) {
// Semi-transparent overlay
Rectangle overlay = {0, 0, (float)SCREEN_WIDTH, (float)SCREEN_HEIGHT};
DrawRectangleRec(overlay, (Color){0, 0, 0, 210});
// Game over text
const char *title = "GAME OVER";
int title_width = MeasureText(title, 60);
DrawText(title, (SCREEN_WIDTH - title_width) / 2, SCREEN_HEIGHT / 2 - 30, 60, RED);
// Title
const char *title = is_victory ? "YOU ESCAPED!" : "GAME OVER";
int title_font_size = is_victory ? 60 : 60;
Color title_color = is_victory ? GOLD : RED;
int title_width = MeasureText(title, title_font_size);
DrawText(title, (SCREEN_WIDTH - title_width) / 2, 30, title_font_size, title_color);
const char *subtitle = "Press R to restart or Q to quit";
int sub_width = MeasureText(subtitle, 20);
DrawText(subtitle, (SCREEN_WIDTH - sub_width) / 2, SCREEN_HEIGHT / 2 + 40, 20, WHITE);
// Stats box
int box_x = SCREEN_WIDTH / 2 - 200;
int box_y = 110;
int box_w = 400;
int box_h = 320;
DrawRectangle(box_x, box_y, box_w, box_h, (Color){20, 20, 20, 240});
DrawRectangleLines(box_x, box_y, box_w, box_h, (Color){100, 100, 100, 255});
// Stats content
char line[64];
int col1_x = box_x + 20;
int col2_x = box_x + 210;
int row_y = box_y + 20;
int line_height = 24;
Color label_color = LIGHTGRAY;
Color value_color = WHITE;
// Column 1
DrawText("Kills:", col1_x, row_y, 18, label_color);
snprintf(line, sizeof(line), "%d", kills);
DrawText(line, col1_x + 80, row_y, 18, value_color);
row_y += line_height;
DrawText("Items:", col1_x, row_y, 18, label_color);
snprintf(line, sizeof(line), "%d", items);
DrawText(line, col1_x + 80, row_y, 18, value_color);
row_y += line_height;
DrawText("Damage Dealt:", col1_x, row_y, 18, label_color);
snprintf(line, sizeof(line), "%d", damage_dealt);
DrawText(line, col1_x + 140, row_y, 18, value_color);
row_y += line_height;
DrawText("Damage Taken:", col1_x, row_y, 18, label_color);
snprintf(line, sizeof(line), "%d", damage_taken);
DrawText(line, col1_x + 140, row_y, 18, value_color);
row_y += line_height;
DrawText("Crits:", col1_x, row_y, 18, label_color);
snprintf(line, sizeof(line), "%d", crits);
DrawText(line, col1_x + 80, row_y, 18, value_color);
row_y += line_height;
DrawText("Times Hit:", col1_x, row_y, 18, label_color);
snprintf(line, sizeof(line), "%d", times_hit);
DrawText(line, col1_x + 80, row_y, 18, value_color);
row_y += line_height;
// Column 2
int col2_row_y = box_y + 20;
DrawText("Potions:", col2_x, col2_row_y, 18, label_color);
snprintf(line, sizeof(line), "%d", potions);
DrawText(line, col2_x + 80, col2_row_y, 18, value_color);
col2_row_y += line_height;
DrawText("Floors:", col2_x, col2_row_y, 18, label_color);
snprintf(line, sizeof(line), "%d", floors);
DrawText(line, col2_x + 80, col2_row_y, 18, value_color);
col2_row_y += line_height;
DrawText("Turns:", col2_x, col2_row_y, 18, label_color);
snprintf(line, sizeof(line), "%d", turns);
DrawText(line, col2_x + 80, col2_row_y, 18, value_color);
col2_row_y += line_height;
// Score: placed below the last row of the longer column (6 items, row_y is already there)
row_y += 10;
DrawText("SCORE:", col1_x, row_y, 22, GOLD);
snprintf(line, sizeof(line), "%d", score);
DrawText(line, col1_x + 90, row_y, 22, GOLD);
if (is_victory) {
const char *subtitle = "Press R to play again or Q to quit";
int sub_width = MeasureText(subtitle, 20);
DrawText(subtitle, (SCREEN_WIDTH - sub_width) / 2, SCREEN_HEIGHT - 50, 20, LIGHTGRAY);
} else {
const char *subtitle = "Press R to restart or Q to quit";
int sub_width = MeasureText(subtitle, 20);
DrawText(subtitle, (SCREEN_WIDTH - sub_width) / 2, SCREEN_HEIGHT - 50, 20, LIGHTGRAY);
}
}
void render_message(const char *message) {

View file

@ -27,8 +27,9 @@ void render_inventory_overlay(const Player *p, int selected);
// Render floating damage text
void render_floating_texts(FloatingText *texts, int count, int shake_x, int shake_y);
// Render game over screen
void render_game_over(void);
// Render end screen (victory or death) with stats breakdown
void render_end_screen(int is_victory, int kills, int items, int damage_dealt, int damage_taken, int crits,
int times_hit, int potions, int floors, int turns, int score);
// Render a message popup
void render_message(const char *message);