Add game over screen
This commit is contained in:
@@ -42,6 +42,8 @@ add_executable(PixelDefense
|
||||
game/ui_widgets.c
|
||||
game/ui_widgets.h
|
||||
game/utils.h
|
||||
game/wave.c
|
||||
game/wave.h
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
10
game/main.c
10
game/main.c
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
33
game/wave.c
Normal 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
42
game/wave.h
Normal 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
|
||||
Reference in New Issue
Block a user