Add game over screen

This commit is contained in:
2024-02-11 16:46:43 +01:00
parent f984ca3163
commit bb54002fa3
8 changed files with 128 additions and 0 deletions

View File

@@ -42,6 +42,8 @@ add_executable(PixelDefense
game/ui_widgets.c
game/ui_widgets.h
game/utils.h
game/wave.c
game/wave.h
)

View File

@@ -97,6 +97,7 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type,
};
switch (type) {
case BUILDING_KEEP:
game->keepEntity = building;
ecs_set(ECS, building, AddPopCapacity, {10});
ecs_set(ECS, building, Storage, {
.stores[RES_WOOD] = true,

View File

@@ -6,9 +6,11 @@
#include "constants.h"
#include "sounds.h"
#include "wave.h"
typedef enum GameScreen {
SCREEN_GAME,
SCREEN_GAME_OVER,
SCREEN_PAUSE_MENU,
SCREEN_MAIN_MENU,
SCREEN_SETTINGS,
@@ -74,6 +76,10 @@ typedef struct Game {
PlayerResources playerResources[PLAYER_COUNT];
Player player;
WaveInfo waveInfo;
ecs_entity_t keepEntity;
BzStackAlloc stackAlloc;
struct {
BzBTNode *workerHarvest;

View File

@@ -463,6 +463,11 @@ void update(float dt, void *userData) {
switch (game->screen) {
case SCREEN_GAME:
updatePlayerInput();
if (!ecs_is_alive(ECS, game->keepEntity)) {
setScreen(game, SCREEN_GAME_OVER);
}
break;
case SCREEN_GAME_OVER:
break;
case SCREEN_PAUSE_MENU:
if (IsKeyReleased(input->mapping.backBtn)) {
@@ -634,6 +639,11 @@ void render(float dt, void *userData) {
renderGame(game, dt);
drawGameUI(game, dt);
break;
case SCREEN_GAME_OVER:
renderGame(game, dt);
drawOverScreen(shadow);
drawGameOverUI(game, dt);
break;
case SCREEN_PAUSE_MENU:
renderGame(game, dt);
drawOverScreen(shadow);

View File

@@ -249,6 +249,39 @@ void drawGameUI(Game *game, f32 dt) {
bzUIEnd(UI);
}
void drawGameOverUI(Game *game, f32 dt) {
i32 width = GetScreenWidth();
i32 height = GetScreenHeight();
bzUIBegin(UI, width, height);
bzUISetParentLayout(UI, (BzUILayout) {
.type = BZ_UI_LAYOUT_FLEX_BOX,
.flags = BZ_UI_FLEX_DIR_COLUMN
});
uiPushDivParentPercentage(1.0f, 0.4f);
bzUISetParentLayout(UI, (BzUILayout) {
.type = BZ_UI_LAYOUT_FLEX_BOX,
.flags = BZ_UI_FLEX_DIR_COLUMN | BZ_UI_FLEX_JUSTIFY_CENTER | BZ_UI_FLEX_ALIGN_CENTER
});
uiMainMenuLabel("Game Over!");
bzUIPopParent(UI);
uiPushDivParentPercentage(1.0f, 0.6f);
bzUISetParentLayout(UI, (BzUILayout) {
.type = BZ_UI_LAYOUT_FLEX_BOX,
.flags = BZ_UI_FLEX_DIR_COLUMN | BZ_UI_FLEX_ALIGN_CENTER
});
uiBaseLabel("You survived 10 rounds.\n\n", game->font, 0.8f, WHITE);
if (uiMainMenuButton("Exit", true)) {
setScreen(game, SCREEN_MAIN_MENU);
unloadMap(game);
loadMap(game, "assets/maps/main_menu_01.tmj");
}
bzUIPopParent(UI);
bzUIEnd(UI);
}
void drawPauseUI(Game *game, f32 dt) {
i32 width = GetScreenWidth();
i32 height = GetScreenHeight();

View File

@@ -241,6 +241,7 @@ void drawPlayerInputUI();
**********************************/
void drawGameUI(Game *game, f32 dt);
void drawGameOverUI(Game *game, f32 dt);
void drawPauseUI(Game *game, f32 dt);
void drawMainMenuUI(Game *game, f32 dt);
void drawSettingsUI(Game *game, f32 dt);

33
game/wave.c Normal file
View File

@@ -0,0 +1,33 @@
#include "wave.h"
WaveInfo getWaveInfo(i32 idx) {
BZ_ASSERT(idx >= 0);
WaveData waveData;
if (idx >= NUM_WAVES) {
waveData = predefWaves[NUM_WAVES - 1];
waveData.difficultyScale += (idx - NUM_WAVES) * 0.1f;
} else {
waveData = predefWaves[idx];
}
WaveInfo info = {
.data = waveData,
.orcsToSend = waveData.numOrcs,
.goblinsToSend = waveData.numGoblins,
};
return info;
}
void updateWave(WaveInfo *wave, f32 dt) {
wave->orcsElapsed += dt;
wave->golbinsElapsed += dt;
wave->elapsed += dt;
}
bool isWaveSendingOver(const WaveInfo *wave) {
return wave->orcsToSend == 0 && wave->goblinsToSend == 0;
}

42
game/wave.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef PIXELDEFENSE_WAVE_H
#define PIXELDEFENSE_WAVE_H
#include <breeze.h>
typedef struct WaveData {
i32 numOrcs; // How many orcs to send
f32 orcSendRate; // How many orcs to send per second
i32 numGoblins; // How many goblins to send
f32 goblinSendRate; // How many goblins to send per second
f32 difficultyScale; // Scale for health and damage
f32 timeBeforeStart; // Time before start sending (seconds)
} WaveData;
typedef struct WaveInfo {
i32 number;
WaveData data;
i32 orcsToSend;
f32 orcsElapsed;
i32 goblinsToSend;
f32 golbinsElapsed;
f32 elapsed;
} WaveInfo;
#define NUM_WAVES 5
static WaveData predefWaves[NUM_WAVES] = {
{ 10, 1.0f, 20, 2.0f, 0, 5 * 60 * 60 },
{ 20, 1.0f, 40, 2.0f, 0, 2 * 60 * 60 },
{ 25, 1.0f, 80, 2.2f, 0, 2 * 60 * 60 },
{ 50, 1.2f, 120, 3.0f, 0, 1.5 * 60 * 60 },
{ 100, 2.0f, 220, 4.0f, 0, 60 * 60 },
};
WaveInfo getWaveInfo(i32 idx);
void updateWave(WaveInfo *wave, f32 dt);
bool isWaveSendingOver(const WaveInfo *wave);
#endif //PIXELDEFENSE_WAVE_H