diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e5eaf8..ff54160 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,8 +15,6 @@ add_executable(PixelDefense game/buildings.h game/components.c game/components.h - game/entity_map.c - game/entity_map.h game/entrypoint.c game/main.c game/map_init.c diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index efcf75d..2b9350d 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -38,6 +38,7 @@ set(BreezeSources breeze/utils/array.c breeze/utils/heap.c breeze/utils/object_pool.c + breeze/utils/spatial_grid.c breeze/utils/tokenizer.c ) @@ -53,6 +54,7 @@ set(BreezeHeaders breeze/utils/array.h breeze/utils/heap.h breeze/utils/object_pool.h + breeze/utils/spatial_grid.h breeze/utils/string.h breeze/utils/tokenizer.h diff --git a/engine/breeze.h b/engine/breeze.h index d825498..92044a1 100644 --- a/engine/breeze.h +++ b/engine/breeze.h @@ -9,6 +9,7 @@ #include "breeze/utils/array.h" #include "breeze/utils/heap.h" #include "breeze/utils/object_pool.h" +#include "breeze/utils/spatial_grid.h" #include "breeze/utils/string.h" #include "breeze/utils/tokenizer.h" diff --git a/engine/breeze/map/tileset.c b/engine/breeze/map/tileset.c index 374c746..ea3903d 100644 --- a/engine/breeze/map/tileset.c +++ b/engine/breeze/map/tileset.c @@ -66,14 +66,14 @@ BzTileset bzTilesetCreate(const BzTilesetDesc *desc) { } } - cute_tiled_free_external_tileset(cuteTileset); if (tileset.tiles.width != cuteTileset->imagewidth || tileset.tiles.height != cuteTileset->imageheight) { + cute_tiled_free_external_tileset(cuteTileset); bzTilesetDestroy(&tileset); return BZ_TILESET_INVALID; } - + cute_tiled_free_external_tileset(cuteTileset); tileset.isValid = true; return tileset; } @@ -107,6 +107,7 @@ BzTileShape bzTilesetGetTileCollider(BzTileset *tileset, BzTile tileID) { void bzTilesetDestroy(BzTileset *tileset) { UnloadTexture(tileset->tiles); + bzFree(tileset->tileColliders); *tileset = BZ_TILESET_INVALID; } diff --git a/engine/breeze/utils/object_pool.c b/engine/breeze/utils/object_pool.c index e6545be..1915795 100644 --- a/engine/breeze/utils/object_pool.c +++ b/engine/breeze/utils/object_pool.c @@ -9,10 +9,6 @@ typedef struct BzObjectPool { i32 firstFree; } BzObjectPool; -static i32 *bzObjectPoolGetObject(const BzObjectPool *pool, size_t idx) { - return (i32 *) ((u8 *) pool->objects + idx * pool->stride); -} - BzObjectPool *bzObjectPoolCreate(const BzObjectPoolDesc *desc) { BZ_ASSERT(desc->objectSize > 0); @@ -53,9 +49,16 @@ void *bzObjectPool(BzObjectPool *pool) { pool->firstFree = *object; return object; } +void *bzObjectPoolGetObject(BzObjectPool *pool, i32 idx) { + BZ_ASSERT(idx >= 0 && (size_t) idx < pool->numObjects); + return (void *) ((u8 *) pool->objects + idx * pool->stride); +} +i32 bzObjectPoolGetIdx(BzObjectPool *pool, void *object) { + size_t objectIdx = (size_t) object - (size_t) pool->numObjects; + return (i32) (objectIdx / pool->stride); +} void bzObjectPoolRelease(BzObjectPool *pool, void *object) { - size_t objectIdx = (size_t) object - (size_t) pool->objects; - objectIdx /= pool->stride; + size_t objectIdx = bzObjectPoolGetIdx(pool, object); BZ_ASSERT(objectIdx < pool->numObjects); *(i32 *) ((u8 *) pool->objects + objectIdx * pool->stride) = pool->firstFree; pool->firstFree = (i32) objectIdx; diff --git a/engine/breeze/utils/object_pool.h b/engine/breeze/utils/object_pool.h index 5650dcd..2cb69d7 100644 --- a/engine/breeze/utils/object_pool.h +++ b/engine/breeze/utils/object_pool.h @@ -14,6 +14,8 @@ BzObjectPool *bzObjectPoolCreate(const BzObjectPoolDesc *desc); void bzObjectPoolDestroy(BzObjectPool *pool); void *bzObjectPool(BzObjectPool *pool); +void *bzObjectPoolGetObject(BzObjectPool *pool, i32 idx); +i32 bzObjectPoolGetIdx(BzObjectPool *pool, void *object); void bzObjectPoolRelease(BzObjectPool *pool, void *object); #endif //BREEZE_OBJECT_POOL_H diff --git a/engine/breeze/utils/spatial_grid.c b/engine/breeze/utils/spatial_grid.c new file mode 100644 index 0000000..7cf21f3 --- /dev/null +++ b/engine/breeze/utils/spatial_grid.c @@ -0,0 +1,226 @@ +#include "spatial_grid.h" + +#include "../core/memory.h" +#include "array.h" +#include "object_pool.h" + +#include + +typedef struct BzSpatialGrid { + BzSpatialGridID **cells; + BzObjectPool *entriesPool; + i32 width; + i32 height; + i32 cellWidth; + i32 cellHeight; + i32 userDataSize; + i32 queryCount; +} BzSpatialGrid; + +static BzSpatialGridID **getCell(const BzSpatialGrid *grid, i32 x, i32 y); + +BzSpatialGrid *bzSpatialGridCreate(const BzSpatialGridDesc *desc) { + i32 width = (desc->maxWidth + desc->cellWidth - 1) / desc->cellWidth; + i32 height = (desc->maxHeight + desc->cellHeight - 1) / desc->cellHeight; + + size_t cellsNumBytes = width * height * sizeof(BzSpatialGridID *); + size_t numBytes = sizeof(BzSpatialGrid) + cellsNumBytes; + BzSpatialGrid *grid = bzAlloc(numBytes); + + grid->width = width; + grid->height = height; + grid->cellWidth = desc->cellWidth; + grid->cellHeight = desc->cellHeight; + grid->userDataSize = desc->userDataSize; + grid->queryCount = 0; + grid->cells = (BzSpatialGridID **) (grid + 1); + for (i32 y = 0; y < grid->height; y++) { + for (i32 x = 0; x < grid->width; x++) { + BzSpatialGridID **cell = getCell(grid, x, y); + *cell = bzArrayCreate(BzSpatialGridID, 4); + } + } + grid->entriesPool = bzObjectPoolCreate(&(BzObjectPoolDesc) { + .objectSize=sizeof(BzSpatialGridEntry) + desc->userDataSize, + .numObjects=1024, + }); + return grid; +} + +void bzSpatialGridDestroy(BzSpatialGrid *grid) { + bzObjectPoolDestroy(grid->entriesPool); + grid->entriesPool = NULL; + for (i32 y = 0; y < grid->height; y++) { + for (i32 x = 0; x < grid->width; x++) { + BzSpatialGridID **cell = getCell(grid, x, y); + bzArrayDestroy(*cell); + *cell = NULL; + } + } + + grid->cells = NULL; + bzFree(grid); +} + +void *bzSpatialGridGetData(const BzSpatialGrid *grid, BzSpatialGridID id) { + return (u8 *)bzObjectPoolGetObject(grid->entriesPool, id) + sizeof(BzSpatialGridEntry); +} + + +static BzSpatialGridID **getCell(const BzSpatialGrid *grid, i32 x, i32 y) { + return grid->cells + y * grid->width + x; +} + +static void insertCell(BzSpatialGrid *grid, BzSpatialGridID id, i32 x, i32 y) { + BzSpatialGridID **cell = getCell(grid, x, y); + bzArrayPush(*cell, id); +} +static void removeCell(BzSpatialGrid *grid, BzSpatialGridID id, i32 x, i32 y) { + BzSpatialGridID **cell = getCell(grid, x, y); + i32 i; + for (i = 0; i < bzArraySize(*cell); i++) { + if (i == (*cell)[i]) { + break; + } + } + if (i < bzArraySize(*cell)) { + BzSpatialGridID lastID = bzArrayPop(*cell); + (*cell)[id] = lastID; + } +} + +static BzSpatialGridIndex calculateGridIndex(BzSpatialGrid *grid, f32 posX, f32 posY, f32 sizeX, f32 sizeY) { + i32 minX = (i32) floorf(posX); + i32 minY = (i32) floorf(posY); + i32 maxX = (i32) floorf(posX + sizeX); + i32 maxY = (i32) floorf(posY + sizeY); + return (BzSpatialGridIndex) { + (i16) (minX / grid->width), + (i16) (minY / grid->height), + (i16) (maxX / grid->width), + (i16) (maxY / grid->height), + }; +} + +BzSpatialGridID bzSpatialGridInsert(BzSpatialGrid *grid, void *data, f32 posX, f32 posY, f32 sizeX, f32 sizeY) { + BzSpatialGridEntry *entry = bzObjectPool(grid->entriesPool); + BZ_ASSERT(entry); + + BzSpatialGridIndex index = calculateGridIndex(grid, posX, posY, sizeX, sizeY); + + BzSpatialGridID id = bzObjectPoolGetIdx(grid->entriesPool, entry); + + for (i32 y = index.minY; y <= index.maxY; y++) { + for (i32 x = index.minX; x <= index.maxX; x++) { + insertCell(grid, id, x, y); + } + } + + entry->id = id; + entry->queryIdx = 0; + entry->index = index; + if (grid->userDataSize) { + bzMemCpy(entry + 1, data, grid->userDataSize); + } + + return id; +} +BzSpatialGridID bzSpatialGridUpdate(BzSpatialGrid *grid, BzSpatialGridID id, f32 posX, f32 posY, f32 sizeX, f32 sizeY) { + BzSpatialGridEntry *entry = bzObjectPoolGetObject(grid->entriesPool, id); + BZ_ASSERT(entry && entry->id == id); + + BzSpatialGridIndex index = calculateGridIndex(grid, posX, posY, sizeX, sizeY); + if (entry->index.minX == index.minX && + entry->index.minY == index.minY && + entry->index.maxX == index.maxX && + entry->index.maxY == index.maxY) { + return id; + } + + return id; +} +void bzSpatialGridRemove(BzSpatialGrid *grid, BzSpatialGridID id) { + BzSpatialGridEntry *entry = bzObjectPoolGetObject(grid->entriesPool, id); + BZ_ASSERT(entry && entry->id == id); + + BzSpatialGridIndex index = entry->index; + for (i32 y = index.minY; y <= index.maxY; y++) { + for (i32 x = index.minX; x <= index.maxX; x++) { + removeCell(grid, id, x, y); + } + } + bzObjectPoolRelease(grid->entriesPool, entry); +} + +BzSpatialGridIter bzSpatialGridIter(BzSpatialGrid *grid, f32 posX, f32 posY, f32 sizeX, f32 sizeY) { + BzSpatialGridIndex index = calculateGridIndex(grid, posX, posY, sizeX, sizeY); + BzSpatialGridIter it = { + .index=index, + ._grid=grid, + ._queryIdx=grid->queryCount++, + ._x=index.minX, + ._y=index.minY, + ._cellIdx=0 + + }; + return it; +} +bool bzSpatialGridQueryNext(BzSpatialGridIter *it) { + BzSpatialGridID **cell = getCell(it->_grid, it->_x, it->_y); + if (it->_cellIdx >= bzArraySize(*cell)) { + it->_cellIdx = 0; + it->_x++; + if (it->_x > it->index.maxX) { + if (it->_y > it->index.maxX) { + it->_y++; + if (it->_y > it->index.maxY) + return false; + } + } + } + + BzSpatialGridID id = bzArrayGet(*cell, it->_cellIdx); + BzSpatialGridEntry *entry = bzObjectPoolGetObject(it->_grid->entriesPool, id); + BZ_ASSERT(entry && id == entry->id); + + it->entry = *entry; + it->data = (void *) (entry + 1); + + it->_cellIdx++; + return true; +} + +#include +#include + +void bzSpatialGridDrawDebugGrid(const BzSpatialGrid *grid) { + // Draw lines + i32 posX = 0; + i32 posY = 0; + for (i32 x = 0; x <= grid->width; x++) { + DrawLine(posX, 0, posX, grid->height * grid->cellHeight, BLACK); + posX += grid->cellWidth; + } + for (i32 y = 0; y <= grid->height; y++) { + DrawLine(0, posY, grid->width * grid->cellWidth, posY, BLACK); + posY += grid->cellHeight; + } + + posX = 0; + posY = 0; + for (i32 y = 0; y < grid->height; y++) { + for (i32 x = 0; x < grid->width; x++) { + BzSpatialGridID **cell = getCell(grid, x, y); + i32 numEntries = 0; + if (*cell) numEntries = bzArraySize(*cell); + char buf[8]; + snprintf(buf, sizeof(buf), "%d", numEntries); + DrawText(buf, posX + 1, posY + 1, 6, WHITE); + + posX += grid->cellWidth; + } + posX = 0; + posY += grid->cellHeight; + } + +} diff --git a/engine/breeze/utils/spatial_grid.h b/engine/breeze/utils/spatial_grid.h new file mode 100644 index 0000000..7a720a4 --- /dev/null +++ b/engine/breeze/utils/spatial_grid.h @@ -0,0 +1,56 @@ +#ifndef BREEZE_SPATIAL_GRID_H +#define BREEZE_SPATIAL_GRID_H + +#include "../defines.h" + +typedef struct BzSpatialGridIndex { + i32 minX, minY; + i32 maxX, maxY; +} BzSpatialGridIndex; + +typedef i32 BzSpatialGridID; + +typedef struct BzSpatialGridEntry { + i32 queryIdx; + BzSpatialGridID id; + BzSpatialGridIndex index; +} BzSpatialGridEntry; + +typedef struct BzSpatialGrid BzSpatialGrid; + +typedef struct BzSpatialGridIter { + BzSpatialGridEntry entry; + void *data; + BzSpatialGridIndex index; + + BzSpatialGrid *_grid; + i32 _queryIdx; + + i32 _x; + i32 _y; + i32 _cellIdx; +} BzSpatialGridIter; + +typedef struct BzSpatialGridDesc { + i32 maxWidth; + i32 maxHeight; + i32 cellWidth; + i32 cellHeight; + i32 userDataSize; +} BzSpatialGridDesc; + +BzSpatialGrid *bzSpatialGridCreate(const BzSpatialGridDesc *desc); +void bzSpatialGridDestroy(BzSpatialGrid *grid); + +//void *bzSpatialGridGetData(const BzSpatialGrid *grid, BzSpatialGridID id); + +BzSpatialGridID bzSpatialGridInsert(BzSpatialGrid *grid, void *data, f32 posX, f32 posY, f32 sizeX, f32 sizeY); +BzSpatialGridID bzSpatialGridUpdate(BzSpatialGrid *grid, BzSpatialGridID id, f32 posX, f32 posY, f32 sizeX, f32 sizeY); +void bzSpatialGridRemove(BzSpatialGrid *grid, BzSpatialGridID id); + +BzSpatialGridIter bzSpatialGridIter(BzSpatialGrid *grid, f32 posX, f32 posY, f32 sizeX, f32 sizeY); +bool bzSpatialGridQueryNext(BzSpatialGridIter *it); + +void bzSpatialGridDrawDebugGrid(const BzSpatialGrid *grid); + +#endif //BREEZE_SPATIAL_GRID_H diff --git a/game/entity_map.c b/game/entity_map.c deleted file mode 100644 index 13b9856..0000000 --- a/game/entity_map.c +++ /dev/null @@ -1,174 +0,0 @@ -#include "entity_map.h" - -#include - -EntityMap entityMapCreate(const EntityMapDesc *desc) { - i32 width = (desc->maxWidth + (desc->cellResolution - 1)) / desc->cellResolution; - i32 height = (desc->maxHeight + (desc->cellResolution - 1)) / desc->cellResolution; - EntityMap map = { - .width=width, - .height=height, - .cellResolution=desc->cellResolution, - .cellDepth=desc->cellDepth, - }; - - size_t numBytes = sizeof(EntityMapCell) * map.width * map.height * map.cellDepth; - map.cells = bzAlloc(numBytes); - bzMemSet(map.cells, 0, numBytes); - map.entities = bzArrayCreate(EntityMapEntry, 512); - - return map; -} -void entityMapDestroy(EntityMap *entityMap) { - bzFree(entityMap->cells); - entityMap->cells = NULL; - bzArrayDestroy(entityMap->entities); - entityMap->entities = NULL; -} - -static EntityMapIndex calculateMapIndex(EntityMap *entityMap, Position pos, Size size) { - i32 minX = (i32) floorf(pos.x); - i32 minY = (i32) floorf(pos.y); - i32 maxX = (i32) floorf(pos.x + size.x); - i32 maxY = (i32) floorf(pos.y + size.y); - return (EntityMapIndex) { - (i16) (minX / entityMap->width), - (i16) (minY / entityMap->height), - (i16) (maxX / entityMap->width), - (i16) (maxY / entityMap->height), - }; -} - -static bool insertMapEntry(EntityMap *entityMap, EntityMapCell idx, i32 x, i32 y) { - EntityMapCell *cell = entityMap->cells + (y * entityMap->width + x) * entityMap->cellDepth; - for (i32 i = 0; i < entityMap->cellResolution; i++) { - if (cell[i] == 0) { - cell[i] = idx; - return true; - } - } - return false; -} -static void removeMapEntry(EntityMap *entityMap, EntityMapCell idx, i32 x, i32 y) { - EntityMapCell *cell = entityMap->cells + (y * entityMap->width + x) * entityMap->cellDepth; - i32 i; - for (i = 0; i < entityMap->cellResolution; i++) { - if (cell[i] == idx) { - break; - } - } - i32 j; - for (j = i; j < entityMap->cellResolution; j++) { - if (cell[j] == 0) { - j--; - break; - } - - } - if (i != j) { - // swap with last - cell[i] = cell[j]; - cell[j] = 0; - } else { - // 'i' is last - cell[i] = 0; - } -} - -EntityMapEntry entityMapInsert(EntityMap *entityMap, ecs_entity_t entity, Position pos, Size size) { - EntityMapEntry entry = {entity}; - EntityMapIndex mapIndex = calculateMapIndex(entityMap, pos, size); - entry.index = mapIndex; - - i32 entryIdx = bzArraySize(entityMap->entities); - entry.entryIdx = entryIdx; - bzArrayPush(entityMap->entities, entry); - - bool wasInserted = true; - - for (i32 y = mapIndex.minY; y <= mapIndex.maxY; y++) { - for (i32 x = mapIndex.minX; x <= mapIndex.maxX; x++) { - wasInserted &= insertMapEntry(entityMap, entryIdx, x, y); - if (!wasInserted) { - entityMapRemoveIdx(entityMap, entryIdx); - return (EntityMapEntry) { - .entity = 0, - }; - } - } - } - - return entry; -} -EntityMapEntry entityMapUpdate(EntityMap *entityMap, EntityMapEntry entry, Position pos, Size size) { - EntityMapEntry check = bzArrayGet(entityMap->entities, entry.entity); - BZ_ASSERT(check.entity == entry.entity); - - EntityMapIndex mapIndex = calculateMapIndex(entityMap, pos, size); - if (entry.index.minX == mapIndex.minX && - entry.index.minY == mapIndex.minY && - entry.index.maxX == mapIndex.maxX && - entry.index.maxY == mapIndex.maxY) { - return entry; - } - - // TODO: Has room for optimization - entityMapRemoveIdx(entityMap, entry.entryIdx); - entityMapInsert(entityMap, entry.entity, pos, size); - -} -void entityMapRemove(EntityMap *entityMap, EntityMapEntry entry) { - entityMapRemoveIdx(entityMap, entry.entryIdx); -} -void entityMapRemoveIdx(EntityMap *entityMap, i32 entryID) { - EntityMapEntry entry = bzArrayGet(entityMap->entities, entryID); - EntityMapIndex index = entry.index; - - for (i32 y = index.minY; y <= index.maxY; y++) { - for (i32 x = index.minX; x <= index.maxX; x++) { - removeMapEntry(entityMap, entryID, x, y); - } - } - - EntityMapEntry last = bzArrayGet(entityMap->entities, bzArraySize(entityMap->entities)); - bzArraySet(entityMap->entities, entryID, last); - bzArrayPop(entityMap->entities); -} - -EntityMapIter entityMapQueryIter(EntityMap *entityMap, Position pos, Size size) { - EntityMapIndex mapIndex = calculateMapIndex(entityMap, pos, size); - EntityMapIter it = { - .entityMap=entityMap, - .queryIdx=entityMap->queryCount++, - .index=mapIndex, - .x=mapIndex.minX, - .y=mapIndex.minY, - .cellIdx=0, - }; - return it; -} -bool entityMapQueryNext(EntityMapIter *it) { - i32 cellOffset = (it->y * it->entityMap->width + it->x) * - it->entityMap->cellDepth + it->cellIdx; - if (it->cellIdx >= it->entityMap->cellDepth || - it->entityMap->cells[cellOffset] == 0) { - it->cellIdx = 0; - it->x++; - if (it->x > it->index.maxX) { - it->y++; - if (it->y > it->index.maxY) - return false; - } - } - it->cellIdx++; - - EntityMapCell cell = it->entityMap->cells[cellOffset]; - EntityMapEntry *entry = &bzArrayGet(it->entityMap->entities, cell); - if (entry->queryIdx == it->queryIdx) { - return entityMapQueryNext(it); - } - entry->queryIdx = it->queryIdx; - it->entry = *entry; - - return true; -} diff --git a/game/entity_map.h b/game/entity_map.h deleted file mode 100644 index fc9e39b..0000000 --- a/game/entity_map.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef PIXELDEFENSE_ENTITY_MAP_H -#define PIXELDEFENSE_ENTITY_MAP_H - -#include -#include - -#include "components.h" - -typedef struct EntityMapIndex { - i32 minX, minY; - i32 maxX, maxY; -} EntityMapIndex; - -typedef struct EntityMapEntry { - ecs_entity_t entity; - i32 queryIdx; - i32 entryIdx; - EntityMapIndex index; -} EntityMapEntry; - -typedef i32 EntityMapCell; - -typedef struct EntityMap { - EntityMapEntry *entities; - EntityMapCell *cells; - i32 width; - i32 height; - i32 cellResolution; - i32 cellDepth; - i32 queryCount; -} EntityMap; - -typedef struct EntityMapDesc { - i32 maxWidth; - i32 maxHeight; - i32 cellResolution; - i32 cellDepth; -} EntityMapDesc; - -typedef struct EntityMapIter { - EntityMap *entityMap; - i32 queryIdx; - EntityMapEntry entry; - EntityMapIndex index; - i32 x; - i32 y; - i32 cellIdx; -} EntityMapIter; - -EntityMap entityMapCreate(const EntityMapDesc *desc); -void entityMapDestroy(EntityMap *entityMap); - -EntityMapEntry entityMapInsert(EntityMap *entityMap, ecs_entity_t entity, Position pos, Size size); -EntityMapEntry entityMapUpdate(EntityMap *entityMap, EntityMapEntry entry, Position pos, Size size); -void entityMapRemove(EntityMap *entityMap, EntityMapEntry entry); -void entityMapRemoveIdx(EntityMap *entityMap, i32 entryID); - -EntityMapIter entityMapQueryIter(EntityMap *entityMap, Position pos, Size size); -bool entityMapQueryNext(EntityMapIter *it); - - - -#endif //PIXELDEFENSE_ENTITY_MAP_H diff --git a/game/game_state.h b/game/game_state.h index 99d7b80..b89cc27 100644 --- a/game/game_state.h +++ b/game/game_state.h @@ -4,8 +4,6 @@ #include #include -#include "entity_map.h" - typedef enum InputState { INPUT_NONE, INPUT_PLACING, @@ -20,7 +18,7 @@ typedef struct Game { BzTileset buildingsTileset; BzTileset entitiesTileset; BzTileMap map; - EntityMap entityMap; + BzSpatialGrid *entityGrid; f32 frameDuration; ecs_entity_t entity; struct { diff --git a/game/main.c b/game/main.c index 7e96d72..562d909 100644 --- a/game/main.c +++ b/game/main.c @@ -32,8 +32,6 @@ bool bzMain(BzAppDesc *appDesc, int argc, const char **argv) { appDesc->render = (BzAppRenderFunc) render; appDesc->imguiRender = (BzAppRenderFunc) imguiRender; - Game *game = bzAlloc(sizeof(*game)); - bzMemSet(game, 0, sizeof(*game)); appDesc->userData = NULL; appDesc->useFlecs = true; @@ -99,11 +97,12 @@ bool init(void *userData) { .objectGroups[OBJECTS_GAME]=(BzTileObjectsDesc) {"Game"}, .objectGroups[OBJECTS_ENTITIES]=(BzTileObjectsDesc ) {"Entities"} }); - game->entityMap = entityMapCreate(&(EntityMapDesc) { + game->entityGrid = bzSpatialGridCreate(&(BzSpatialGridDesc) { .maxWidth=game->map.width * game->map.tileWidth, .maxHeight=game->map.height * game->map.tileHeight, - .cellResolution=game->map.tileWidth, - .cellDepth=16 + .cellWidth=game->map.tileWidth * 2, + .cellHeight=game->map.tileHeight * 2, + .userDataSize=sizeof(ecs_entity_t) }); bzTileMapOverrideLayer(&game->map, LAYER_BUILDING_OWNER, initBuildingsLayer); @@ -129,6 +128,10 @@ void deinit(void *userData) { bzTilesetDestroy(&game->buildingsTileset); bzTilesetDestroy(&game->entitiesTileset); + + bzObjectPoolDestroy(game->pools.pathData); + bzSpatialGridDestroy(game->entityGrid); + ecs_singleton_remove(ECS, Game); } @@ -226,6 +229,8 @@ void render(float dt, void *userData) { game->input.buildingSize.sizeY * height, placeColor); } + bzSpatialGridDrawDebugGrid(game->entityGrid); + Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera); int tileX = (int) worldPos.x / 16;