Remove multiple colliders, add spatial index component
This commit is contained in:
@@ -37,30 +37,27 @@ bool canPlaceBuilding(BzTileMap *map, BuildingType type, BzTile tileX, BzTile ti
|
||||
if (tile == BUILDINGS_ROAD)
|
||||
return false;
|
||||
}
|
||||
BzTileCollider collider = bzTileMapGetCollider(map, x, y);
|
||||
BzTileShape shape = bzTileMapGetCollider(map, x, y);
|
||||
f32 posX = x * map->tileWidth;
|
||||
f32 posY = y * map->tileHeight;
|
||||
for (int i = 0; i < BZ_MAP_COLLIDER_DEPTH; i++) {
|
||||
BzTileShape shape = collider.shapes[i];
|
||||
shape.x += posX;
|
||||
shape.y += posY;
|
||||
switch (shape.type) {
|
||||
case BZ_TILE_SHAPE_NONE:
|
||||
case BZ_TILE_SHAPE_POINT:
|
||||
break;
|
||||
case BZ_TILE_SHAPE_RECT: {
|
||||
Rectangle shapeRec = {shape.x, shape.y, shape.sizeX, shape.sizeY};
|
||||
if (CheckCollisionRecs(buildArea, shapeRec))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case BZ_TILE_SHAPE_ELLIPSE: {
|
||||
Vector2 pos = {shape.x, shape.y};
|
||||
f32 radius = (shape.sizeX + shape.sizeY) * 0.5f;
|
||||
if (CheckCollisionCircleRec(pos, radius, buildArea))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
shape.x += posX;
|
||||
shape.y += posY;
|
||||
switch (shape.type) {
|
||||
case BZ_TILE_SHAPE_NONE:
|
||||
case BZ_TILE_SHAPE_POINT:
|
||||
break;
|
||||
case BZ_TILE_SHAPE_RECT: {
|
||||
Rectangle shapeRec = {shape.x, shape.y, shape.sizeX, shape.sizeY};
|
||||
if (CheckCollisionRecs(buildArea, shapeRec))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case BZ_TILE_SHAPE_ELLIPSE: {
|
||||
Vector2 pos = {shape.x, shape.y};
|
||||
f32 radius = (shape.sizeX + shape.sizeY) * 0.5f;
|
||||
if (CheckCollisionCircleRec(pos, radius, buildArea))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,9 +79,9 @@ ecs_entity_t placeBuilding(BzTileMap *map, BuildingType type, BzTile tileX, BzTi
|
||||
// Create entity
|
||||
ecs_entity_t e = ecs_new_id(ECS);
|
||||
|
||||
ecs_set(ECS, e, TilePosition, {.x=tileX, .y=tileY});
|
||||
ecs_set(ECS, e, TileSize, {.sizeX=sizeX, .sizeY=sizeY});
|
||||
ecs_set(ECS, e, Owner, {.playerID=BUILDINGS_PLAYER_RED});
|
||||
ecs_set(ECS, e, TilePosition, { .x = tileX, .y = tileY });
|
||||
ecs_set(ECS, e, TileSize, { .sizeX = sizeX, .sizeY = sizeY });
|
||||
ecs_set(ECS, e, Owner, { .playerID = BUILDINGS_PLAYER_RED });
|
||||
|
||||
for (i32 y = tileY; y < tileY + sizeY; y++) {
|
||||
for (i32 x = tileX; x < tileX + sizeX; x++) {
|
||||
@@ -92,7 +89,7 @@ ecs_entity_t placeBuilding(BzTileMap *map, BuildingType type, BzTile tileX, BzTi
|
||||
bzTileLayerSetTile(buildingLayer, layerTile, x, y, 1, 1);
|
||||
buildingTile++;
|
||||
|
||||
bzTileMapUpdateCollider(map, x, y);
|
||||
bzTileMapUpdateColliders(map, x, y, 1, 1);
|
||||
}
|
||||
buildingTile += buildingTileset->width - sizeX;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ ECS_COMPONENT_DECLARE(Position);
|
||||
ECS_COMPONENT_DECLARE(Size);
|
||||
ECS_COMPONENT_DECLARE(TargetPosition);
|
||||
ECS_COMPONENT_DECLARE(MoveForce);
|
||||
ECS_COMPONENT_DECLARE(SpatialGridID);
|
||||
ECS_COMPONENT_DECLARE(Rotation);
|
||||
ECS_COMPONENT_DECLARE(Health);
|
||||
ECS_COMPONENT_DECLARE(TextureRegion);
|
||||
@@ -23,6 +24,7 @@ void initComponentIDs(ecs_world_t *ecs) {
|
||||
ECS_COMPONENT_DEFINE(ecs, Size);
|
||||
ECS_COMPONENT_DEFINE(ecs, TargetPosition);
|
||||
ECS_COMPONENT_DEFINE(ecs, MoveForce);
|
||||
ECS_COMPONENT_DEFINE(ecs, SpatialGridID);
|
||||
ECS_COMPONENT_DEFINE(ecs, Rotation);
|
||||
ECS_COMPONENT_DEFINE(ecs, Health);
|
||||
ECS_COMPONENT_DEFINE(ecs, TextureRegion);
|
||||
|
||||
@@ -32,6 +32,9 @@ extern ECS_COMPONENT_DECLARE(Size);
|
||||
extern ECS_COMPONENT_DECLARE(TargetPosition);
|
||||
extern ECS_COMPONENT_DECLARE(MoveForce);
|
||||
|
||||
typedef BzSpatialGridID SpatialGridID;
|
||||
extern ECS_COMPONENT_DECLARE(SpatialGridID);
|
||||
|
||||
typedef f32 Rotation;
|
||||
extern ECS_COMPONENT_DECLARE(Rotation);
|
||||
|
||||
|
||||
10
game/main.c
10
game/main.c
@@ -83,15 +83,16 @@ bool init(void *userData) {
|
||||
|
||||
game->map = bzTileMapCreate(&(BzTileMapDesc) {
|
||||
.path="assets/maps/test.tmj",
|
||||
.generateColliderMap=true,
|
||||
.tilesets[0]=game->terrainTileset,
|
||||
.tilesets[1]=game->buildingsTileset,
|
||||
.tilesets[2]=game->entitiesTileset,
|
||||
|
||||
.layers[LAYER_TERRAIN]=(BzTileLayerDesc) {"Terrain"},
|
||||
.layers[LAYER_TERRAIN]=(BzTileLayerDesc) {"Terrain", .applyColliders=true},
|
||||
.layers[LAYER_FOLIAGE]=(BzTileLayerDesc) {"Foliage"},
|
||||
.layers[LAYER_TREES]=(BzTileLayerDesc) {"Trees"},
|
||||
.layers[LAYER_TREES2]=(BzTileLayerDesc) {"TreesS"},
|
||||
.layers[LAYER_BUILDINGS]=(BzTileLayerDesc) {"Buildings"},
|
||||
.layers[LAYER_BUILDINGS]=(BzTileLayerDesc) {"Buildings", .applyColliders=true},
|
||||
.layers[LAYER_BUILDING_OWNER]=(BzTileLayerDesc) {"BuildingOwnership", BZ_TILE_LAYER_SKIP_RENDER},
|
||||
|
||||
.objectGroups[OBJECTS_GAME]=(BzTileObjectsDesc) {"Game"},
|
||||
@@ -100,8 +101,8 @@ bool init(void *userData) {
|
||||
game->entityGrid = bzSpatialGridCreate(&(BzSpatialGridDesc) {
|
||||
.maxWidth=game->map.width * game->map.tileWidth,
|
||||
.maxHeight=game->map.height * game->map.tileHeight,
|
||||
.cellWidth=game->map.tileWidth * 2,
|
||||
.cellHeight=game->map.tileHeight * 2,
|
||||
.cellWidth=game->map.tileWidth * 5,
|
||||
.cellHeight=game->map.tileHeight * 5,
|
||||
.userDataSize=sizeof(ecs_entity_t)
|
||||
});
|
||||
|
||||
@@ -113,6 +114,7 @@ bool init(void *userData) {
|
||||
ECS_SYSTEM(ECS, uiTask, EcsOnUpdate, 0);
|
||||
ECS_SYSTEM(ECS, updateAnimations, EcsOnUpdate, Animation, TextureRegion);
|
||||
ECS_SYSTEM(ECS, updatePos, EcsOnUpdate, Position, TargetPosition, TextureRegion);
|
||||
ECS_SYSTEM(ECS, entityUpdatePhysics, EcsOnUpdate, Position, Size, SpatialGridID);
|
||||
ECS_SYSTEM(ECS, drawDebugPath, EcsOnUpdate, Path);
|
||||
ECS_SYSTEM(ECS, renderEntities, EcsOnUpdate, Position, Size, Rotation, TextureRegion);
|
||||
ECS_OBSERVER(ECS, targetFinish, EcsOnRemove, TargetPosition);
|
||||
|
||||
@@ -29,6 +29,10 @@ bool initEntityObjectsLayer(BzTileMap *map, BzTileObjectGroup *objectGroup) {
|
||||
game->entity = e;
|
||||
ecs_set(ECS, e, Position, {object.shape.x, object.shape.y});
|
||||
ecs_set(ECS, e, Size, {object.shape.sizeX, object.shape.sizeY});
|
||||
BzSpatialGridID spatialID = bzSpatialGridInsert(game->entityGrid, &e,
|
||||
object.shape.x, object.shape.y,
|
||||
object.shape.sizeX, object.shape.sizeY);
|
||||
ecs_set(ECS, e, SpatialGridID, {spatialID});
|
||||
ecs_set(ECS, e, Rotation, {0.0f});
|
||||
ecs_set(ECS, e, TextureRegion, {objectTileset->tiles, bzTilesetGetTileRegion(objectTileset, object.gid)});
|
||||
ecs_set(ECS, e, Animation, {
|
||||
|
||||
@@ -54,7 +54,7 @@ bool findPath(const PathfindingDesc *desc) {
|
||||
if (y < 0 || y >= map->height ||
|
||||
x < 0 || x >= map->width)
|
||||
continue;
|
||||
if (bzTileMapGetCollider(map, x, y).shapes[0].type != BZ_TILE_SHAPE_NONE)
|
||||
if (bzTileMapGetCollider(map, x, y).type != BZ_TILE_SHAPE_NONE)
|
||||
continue;
|
||||
Visited *curVisited = &visited[y * map->width + x];
|
||||
if (curVisited->visited)
|
||||
@@ -91,6 +91,7 @@ bool findPath(const PathfindingDesc *desc) {
|
||||
pathData->next = NULL;
|
||||
i32 numWaypoints = 0;
|
||||
// Write path
|
||||
// TODO: Write end pos
|
||||
while (pos.x != desc->start.x || pos.y != desc->start.y) {
|
||||
Position waypoint = {
|
||||
pos.x * map->tileWidth + map->tileWidth * 0.5f,
|
||||
@@ -113,6 +114,10 @@ bool findPath(const PathfindingDesc *desc) {
|
||||
pos.y -= visit.y;
|
||||
pathLen++;
|
||||
}
|
||||
if (pathLen == 0) {
|
||||
bzObjectPoolRelease(desc->pool, pathData);
|
||||
pathData = NULL;
|
||||
}
|
||||
out->paths = pathData;
|
||||
|
||||
// Reverse paths
|
||||
|
||||
@@ -22,7 +22,9 @@ void entityAdded(ecs_iter_t *it);
|
||||
/*
|
||||
* 0: Game (singleton)
|
||||
* 1: Position
|
||||
* 2: MoveForce
|
||||
* 2: Size
|
||||
* 3: MoveForce
|
||||
* 4: SpatialGridID
|
||||
*/
|
||||
void entityUpdatePhysics(ecs_iter_t *it);
|
||||
|
||||
|
||||
@@ -12,6 +12,19 @@ void entityAdded(ecs_iter_t *it) {
|
||||
|
||||
}
|
||||
void entityUpdatePhysics(ecs_iter_t *it) {
|
||||
Game *game = ecs_singleton_get_mut(ECS, Game);
|
||||
Position *pos = ecs_field(it, Position, 1);
|
||||
Size *size = ecs_field(it, Size, 2);
|
||||
//MoveForce *force = ecs_field(it, MoveForce, 3);
|
||||
SpatialGridID *spatialID = ecs_field(it, SpatialGridID, 3);
|
||||
|
||||
for (i32 i = 0; i < it->count; i++) {
|
||||
//bzSpatialGridUpdate(game->entityGrid, spatialID[i], pos[i].x, pos[i].y, size[i].x, size[i].y);
|
||||
ecs_entity_t *e = bzSpatialGridGetData(game->entityGrid, spatialID[i]);
|
||||
BZ_ASSERT(*e == it->entities[i]);
|
||||
bzSpatialGridRemove(game->entityGrid, spatialID[i]);
|
||||
spatialID[i] = bzSpatialGridInsert(game->entityGrid, &(it->entities[i]), pos[i].x, pos[i].y, size[i].x, size[i].y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +59,7 @@ void renderEntities(ecs_iter_t *it) {
|
||||
if (t[i].flipX) src.width *= -1.0f;
|
||||
if (t[i].flipY) src.height *= -1.0f;
|
||||
DrawTexturePro(t[i].texture, src, dst, origin, r[i], WHITE);
|
||||
DrawRectangleLines(dst.x - dst.width * 0.5f, dst.y, dst.width, dst.height, RED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +88,7 @@ void updatePos(ecs_iter_t *it) {
|
||||
#include <stdlib.h>
|
||||
void targetFinish(ecs_iter_t *it) {
|
||||
const Game *game = ecs_singleton_get(ECS, Game);
|
||||
if (game == NULL) return;
|
||||
|
||||
for (i32 i = 0; i < it->count; i++) {
|
||||
ecs_entity_t e = it->entities[i];
|
||||
|
||||
Reference in New Issue
Block a user