Finish main menu screen

This commit is contained in:
2024-02-12 17:18:37 +01:00
parent 10c6d74e90
commit abaa778aab
9 changed files with 759 additions and 491 deletions

View File

@@ -79,6 +79,7 @@ typedef struct Game {
PlayerResources playerResources[PLAYER_COUNT];
Player player;
EnemyWaves waves;
WaveInfo waveInfo;
ecs_entity_t keepEntity;

View File

@@ -359,7 +359,7 @@ bool init(void *userData) {
SetTextureFilter(game->tileset.tiles, TEXTURE_FILTER_POINT);
setupSystems();
loadMap(game, "assets/maps/main_menu_01.tmj");
loadMap(game, "assets/maps/main_menu_01.tmj", true);
game->debug.drawMapColliders = false;
@@ -615,7 +615,7 @@ static void renderGame(Game *game, float dt) {
static f32 waveDisplay = 0.0f;
if (isWaveOver(&game->waveInfo)) {
game->waveInfo = getWaveInfo(game->waveInfo.number + 1);
game->waveInfo = getWaveInfo(&game->waves, game->waveInfo.number + 1);
waveDisplay = 1.6f;
}

View File

@@ -10,6 +10,7 @@
#include "map_layers.h"
#include "utils.h"
#include "systems/systems.h"
#include "raymath.h"
i32 getSwarmWaypointIdx(u32 id) {
char buf[4];
@@ -260,7 +261,7 @@ void terrainRender(BzTileMap *map, BzTileLayer *layer) {
drawPos.y += (float) tileset->tileHeight;
}
}
void loadMap(Game *game, const char *path) {
void loadMap(Game *game, const char *path, bool mainMenu) {
game->map = bzTileMapCreate(&(BzTileMapDesc) {
.path=path,
@@ -293,7 +294,8 @@ void loadMap(Game *game, const char *path) {
game->camera.zoom = 3.0f;
bzMemSet(game->playerResources, 0, sizeof(*game->playerResources));
game->waveInfo = getWaveInfo(0);
game->waves = mainMenu ? getMainMenuWaves() : getDefaultWaves();
game->waveInfo = getWaveInfo(&game->waves, 0);
bzTileMapAddLayerCollisions(&game->map, LAYER_TERRAIN, COLL_LAYER_TERRAIN);
@@ -309,6 +311,90 @@ void loadMap(Game *game, const char *path) {
bzTileMapOverrideObjectGroup(&game->map, OBJECTS_GAME, initGameObjectsLayer);
bzTileMapOverrideObjectGroup(&game->map, OBJECTS_ENTITIES, initEntityObjectsLayer);
if (mainMenu) {
// Auto assign jobs
i32 numWorkers = ecs_count_id(ECS, ecs_id(Worker));
i32 numHarvestables = ecs_count_id(ECS, ecs_id(Harvestable));
typedef struct PosPair {
ecs_entity_t entity;
Position pos;
} PosPair;
PosPair *workers = bzStackAlloc(&game->stackAlloc, sizeof(*workers) * numWorkers);
PosPair *harvestables = bzStackAlloc(&game->stackAlloc, sizeof(*harvestables) * numWorkers);
i32 workerIdx = 0;
ecs_filter_t *workerFilter = ecs_filter(ECS, {
.terms = {{ecs_id(Position)}, {ecs_id(Worker)}}
});
ecs_iter_t it = ecs_filter_iter(ECS, workerFilter);
while (ecs_filter_next(&it)) {
Position *pos = ecs_field(&it, Position, 1);
for (i32 i = 0; i < it.count; i++) {
if (workerIdx >= numWorkers)
break;
workers[workerIdx++] = (PosPair) {
it.entities[i],
pos[i]
};
}
}
ecs_filter_fini(workerFilter);
i32 harvestableIdx = 0;
ecs_filter_t *harvestableFilter = ecs_filter(ECS, {
.terms = {{ecs_id(Position)}, {ecs_id(Harvestable)}}
});
it = ecs_filter_iter(ECS, harvestableFilter);
while (ecs_filter_next(&it)) {
Position *pos = ecs_field(&it, Position, 1);
for (i32 i = 0; i < it.count; i++) {
if (harvestableIdx >= numHarvestables)
break;
harvestables[harvestableIdx++] = (PosPair) {
it.entities[i],
pos[i]
};
}
}
ecs_filter_fini(harvestableFilter);
bzLogInfo("%d %d", workerIdx, harvestableIdx);
for (i32 i = 0; i < workerIdx; i++) {
PosPair nearest = harvestables[0];
f32 dst = INFINITY;
for (i32 j = 1; j < harvestableIdx; j++) {
if (nearest.entity == 0) continue;
f32 jDst = Vector2Distance(workers[i].pos, harvestables[j].pos);
if (jDst < dst) {
nearest = harvestables[j];
dst = jDst;
}
}
if (nearest.entity == 0) continue;
ResourceType resType = ecs_get(ECS, nearest.entity, Resource)->type;
setAIBehaviour(workers[i].entity, game->BTs.workerHarvest, &(AIBlackboard) {
.as.worker = {
.harvestType = resType,
.harvestTarget = nearest.entity,
.harvestPos = nearest.pos
},
.proximity = 3.0f,
});
Worker *worker = ecs_get_mut(ECS, workers[i].entity, Worker);
worker->carryRes = resType;
}
bzStackAllocFree(&game->stackAlloc, harvestables);
bzStackAllocFree(&game->stackAlloc, workers);
}
}
void unloadMap(Game *game) {
ecs_delete_with(ECS, GameEntity);

View File

@@ -18,7 +18,7 @@ bool initTreesLayer(BzTileMap *map, BzTileLayer *layer);
typedef struct Game Game;
void loadMap(Game *game, const char *path);
void loadMap(Game *game, const char *path, bool mainMenu);
void unloadMap(Game *game);
#endif //PIXELDEFENSE_MAP_INITIALIZATION_H

View File

@@ -319,7 +319,7 @@ void drawGameOverUI(Game *game, f32 dt) {
if (uiMainMenuButton("Exit", true)) {
setScreen(game, SCREEN_MAIN_MENU);
unloadMap(game);
loadMap(game, "assets/maps/main_menu_01.tmj");
loadMap(game, "assets/maps/main_menu_01.tmj", true);
}
bzUIPopParent(UI);
bzUIEnd(UI);
@@ -354,7 +354,7 @@ void drawPauseUI(Game *game, f32 dt) {
if (uiMainMenuButton("Exit", true)) {
setScreen(game, SCREEN_MAIN_MENU);
unloadMap(game);
loadMap(game, "assets/maps/main_menu_01.tmj");
loadMap(game, "assets/maps/main_menu_01.tmj", true);
}
bzUIPopParent(UI);
bzUIEnd(UI);
@@ -392,7 +392,7 @@ void drawMainMenuUI(Game *game, f32 dt) {
//loadMap(game, "assets/maps/entity_test.tmj");
//loadMap(game, "assets/maps/worker_test.tmj");
//loadMap(game, "assets/maps/battle_test.tmj");
loadMap(game, "assets/maps/map_01.tmj");
loadMap(game, "assets/maps/map_01.tmj", false);
}
if (uiMainMenuButton("Settings", true)) {
setScreen(game, SCREEN_SETTINGS);

View File

@@ -4,15 +4,40 @@
#include "entity_factory.h"
#include "utils.h"
WaveInfo getWaveInfo(i32 idx) {
#define NUM_WAVES 5
EnemyWaves getDefaultWaves() {
static WaveData waves[NUM_WAVES] = {
{ 10, 1.0f, 20, 2.0f, 0, 5 * 60 },
{ 20, 1.0f, 40, 2.0f, 0, 2 * 60 },
{ 25, 1.0f, 80, 2.2f, 0, 2 * 60 },
{ 50, 1.2f, 120, 3.0f, 0, 1.5f * 60 },
{ 100, 2.0f, 220, 4.0f, 0, 1.0f * 60 },
};
return (EnemyWaves) {
.numWaves = NUM_WAVES,
.waves = waves
};
}
EnemyWaves getMainMenuWaves() {
static WaveData waves[1] = {
{ 100000, 0.2f, 2000000, 0.8f, 0, 0 }
};
return (EnemyWaves) {
.numWaves = 1,
.waves = waves
};
}
WaveInfo getWaveInfo(const EnemyWaves *waves, i32 idx) {
BZ_ASSERT(idx >= 0);
WaveData waveData;
if (idx >= NUM_WAVES) {
waveData = predefWaves[NUM_WAVES - 1];
waveData.difficultyScale += (idx - NUM_WAVES) * 0.1f;
if (idx >= waves->numWaves) {
waveData = waves->waves[waves->numWaves - 1];
waveData.difficultyScale += (idx - waves->numWaves) * 0.1f;
} else {
waveData = predefWaves[idx];
waveData = waves->waves[idx];
}
WaveInfo info = {

View File

@@ -23,19 +23,18 @@ typedef struct WaveInfo {
bool started;
} WaveInfo;
#define NUM_WAVES 5
typedef struct EnemyWaves {
i32 numWaves;
const WaveData *waves;
} EnemyWaves;
typedef struct Game Game;
static WaveData predefWaves[NUM_WAVES] = {
{ 10, 1.0f, 20, 2.0f, 0, 5 * 60 },
{ 20, 1.0f, 40, 2.0f, 0, 2 * 60 },
{ 25, 1.0f, 80, 2.2f, 0, 2 * 60 },
{ 50, 1.2f, 120, 3.0f, 0, 1.5f * 60 },
{ 100, 2.0f, 220, 4.0f, 0, 1.0f * 60 },
};
EnemyWaves getDefaultWaves();
EnemyWaves getMainMenuWaves();
WaveInfo getWaveInfo(i32 idx);
WaveInfo getWaveInfo(const EnemyWaves *waves, i32 idx);
void updateWave(WaveInfo *wave, Game *game, f32 dt);