diff --git a/engine/breeze/game.h b/engine/breeze/game.h index 328c55c..4299b90 100644 --- a/engine/breeze/game.h +++ b/engine/breeze/game.h @@ -20,22 +20,14 @@ typedef struct BzAppDesc { BzAppRenderFunc imguiRender; BzAppDeinitFunc deinit; - bool useFlecs; - void *userData; } BzAppDesc; -typedef struct ecs_world_t ecs_world_t; -extern ecs_world_t *ECS; - extern bool bzMain(BzAppDesc *appDesc, int argc, const char **argv); #ifdef BZ_ENTRYPOINT -#include #include -ecs_world_t *ECS = NULL; - // https://www.raylib.com/examples/core/loader.html?name=core_custom_logging static void bzRaylibLogger(int msgType, const char *text, va_list args) { BzLoggerLevel level = BZ_LOG_TRACE; @@ -94,8 +86,6 @@ int main(int argc, const char **argv) { SetTargetFPS(appDesc.fps); // Initialize modules - if (appDesc.useFlecs) - ECS = ecs_init(); if (appDesc.imguiRender) rlImGuiSetup(true); @@ -131,10 +121,6 @@ int main(int argc, const char **argv) { // Deinitialize modules if (appDesc.imguiRender) rlImGuiShutdown(); - if (ECS) { - ecs_fini(ECS); - ECS = NULL; - } CloseWindow(); bzLoggerDeinit(); diff --git a/game/components.c b/game/components.c index a50e8b2..9f27490 100644 --- a/game/components.c +++ b/game/components.c @@ -4,17 +4,21 @@ ECS_TAG_DECLARE(TextureTerrain); ECS_TAG_DECLARE(TextureBuildings); ECS_TAG_DECLARE(TextureEntities); +ECS_COMPONENT_DECLARE(Resource); + ECS_COMPONENT_DECLARE(TilePosition); ECS_COMPONENT_DECLARE(TileSize); ECS_COMPONENT_DECLARE(Owner); + +ECS_COMPONENT_DECLARE(SpatialGridID); + ECS_COMPONENT_DECLARE(Position); ECS_COMPONENT_DECLARE(Size); -ECS_COMPONENT_DECLARE(TargetPosition); -ECS_COMPONENT_DECLARE(MoveForce); -ECS_COMPONENT_DECLARE(Resource); -ECS_COMPONENT_DECLARE(SpatialGridID); +ECS_COMPONENT_DECLARE(Velocity); ECS_COMPONENT_DECLARE(Rotation); -ECS_COMPONENT_DECLARE(Health); +ECS_COMPONENT_DECLARE(AngularVelocity); +ECS_COMPONENT_DECLARE(SteeringOutput); + ECS_COMPONENT_DECLARE(TextureRegion); ECS_COMPONENT_DECLARE(AnimationType); ECS_COMPONENT_DECLARE(Animation); @@ -25,17 +29,21 @@ void initComponentIDs(ecs_world_t *ecs) { ECS_TAG_DEFINE(ecs, TextureBuildings); ECS_TAG_DEFINE(ecs, TextureEntities); + ECS_COMPONENT_DEFINE(ecs, Resource); + ECS_COMPONENT_DEFINE(ecs, TilePosition); ECS_COMPONENT_DEFINE(ecs, TileSize); ECS_COMPONENT_DEFINE(ecs, Owner); + + ECS_COMPONENT_DEFINE(ecs, SpatialGridID); + ECS_COMPONENT_DEFINE(ecs, Position); ECS_COMPONENT_DEFINE(ecs, Size); - ECS_COMPONENT_DEFINE(ecs, TargetPosition); - ECS_COMPONENT_DEFINE(ecs, MoveForce); - ECS_COMPONENT_DEFINE(ecs, Resource); - ECS_COMPONENT_DEFINE(ecs, SpatialGridID); + ECS_COMPONENT_DEFINE(ecs, Velocity); ECS_COMPONENT_DEFINE(ecs, Rotation); - ECS_COMPONENT_DEFINE(ecs, Health); + ECS_COMPONENT_DEFINE(ecs, AngularVelocity); + ECS_COMPONENT_DEFINE(ecs, SteeringOutput); + ECS_COMPONENT_DEFINE(ecs, TextureRegion); ECS_COMPONENT_DEFINE(ecs, AnimationType); ECS_COMPONENT_DEFINE(ecs, Animation); diff --git a/game/components.h b/game/components.h index 137878a..61364b0 100644 --- a/game/components.h +++ b/game/components.h @@ -10,6 +10,20 @@ extern ECS_TAG_DECLARE(TextureTerrain); extern ECS_TAG_DECLARE(TextureBuildings); extern ECS_TAG_DECLARE(TextureEntities); +typedef enum ResourceType { + RES_IRON, + RES_WOOD, + RES_GOLD, + RES_FOOD, + RES_COUNT, +} ResourceType; + +typedef struct Resource { + ResourceType type; + i32 amount; +} Resource; +extern ECS_COMPONENT_DECLARE(Resource); + typedef struct TilePosition { BzTile x; BzTile y; @@ -27,34 +41,21 @@ typedef struct Owner { } Owner; extern ECS_COMPONENT_DECLARE(Owner); -typedef Vector2 Position, Size, TargetPosition, MoveForce; -extern ECS_COMPONENT_DECLARE(Position); -extern ECS_COMPONENT_DECLARE(Size); -extern ECS_COMPONENT_DECLARE(TargetPosition); -extern ECS_COMPONENT_DECLARE(MoveForce); - -typedef enum ResourceType { - RES_IRON, - RES_WOOD, - RES_GOLD, - RES_FOOD, - RES_COUNT, -} ResourceType; - -typedef struct Resource { - ResourceType type; - i32 amount; -} Resource; -extern ECS_COMPONENT_DECLARE(Resource); - typedef BzSpatialGridID SpatialGridID; extern ECS_COMPONENT_DECLARE(SpatialGridID); -typedef f32 Rotation; +typedef Vector2 Position, Size, Velocity; +extern ECS_COMPONENT_DECLARE(Position); +extern ECS_COMPONENT_DECLARE(Size); +extern ECS_COMPONENT_DECLARE(Velocity); +typedef f32 Rotation, AngularVelocity; extern ECS_COMPONENT_DECLARE(Rotation); - -typedef f32 Health; -extern ECS_COMPONENT_DECLARE(Health); +extern ECS_COMPONENT_DECLARE(AngularVelocity); +typedef struct SteeringOutput { + Vector2 linear; + f32 angular; +} SteeringOutput; +extern ECS_COMPONENT_DECLARE(SteeringOutput); typedef struct TextureRegion { Texture2D texture; diff --git a/game/game_state.h b/game/game_state.h index b89cc27..a37b473 100644 --- a/game/game_state.h +++ b/game/game_state.h @@ -43,6 +43,8 @@ typedef struct Game { f32 elapsed; } Game; +extern ecs_world_t *ECS; + extern ECS_COMPONENT_DECLARE(Game); #endif //PIXELDEFENSE_GAME_STATE_H diff --git a/game/main.c b/game/main.c index c71004b..4234432 100644 --- a/game/main.c +++ b/game/main.c @@ -12,6 +12,8 @@ ECS_COMPONENT_DECLARE(Game); +ecs_world_t *ECS = NULL; + bool init(void *userData); void deinit(void *userData); @@ -33,14 +35,15 @@ bool bzMain(BzAppDesc *appDesc, int argc, const char **argv) { appDesc->imguiRender = (BzAppRenderFunc) imguiRender; appDesc->userData = NULL; - appDesc->useFlecs = true; - return true; } bool init(void *userData) { BZ_UNUSED(userData); - SetExitKey(-1); + SetExitKey(KEY_ESCAPE); + + ECS = ecs_init(); + ECS_COMPONENT_DEFINE(ECS, Game); initComponentIDs(ECS); @@ -114,12 +117,10 @@ bool init(void *userData) { bzTileMapOverrideObjectGroup(&game->map, OBJECTS_GAME, initGameObjectsLayer); bzTileMapOverrideObjectGroup(&game->map, OBJECTS_ENTITIES, initEntityObjectsLayer); - 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_OBSERVER(ECS, entitySpatialRemoved, EcsOnRemove, Position, SpatialGridID); + ECS_OBSERVER(ECS, pathRemoved, EcsOnRemove, Path); - ECS_SYSTEM(ECS, drawDebugPath, EcsOnUpdate, Path); + ECS_SYSTEM(ECS, renderDebugPath, EcsOnUpdate, Path); ECS_SYSTEM(ECS, renderTerrain, EcsOnUpdate, Position, Size, Rotation, TextureRegion, TextureTerrain); ECS_SYSTEM(ECS, renderBuildings, EcsOnUpdate, Position, Size, Rotation, TextureRegion, TextureBuildings); @@ -127,8 +128,6 @@ bool init(void *userData) { ECS_SYSTEM(ECS, renderColliders, EcsOnUpdate, Position, Size); - ECS_OBSERVER(ECS, targetFinish, EcsOnRemove, TargetPosition); - ECS_OBSERVER(ECS, startPath, EcsOnSet, Path); return true; } void deinit(void *userData) { @@ -140,11 +139,11 @@ void deinit(void *userData) { bzTilesetDestroy(&game->buildingsTileset); bzTilesetDestroy(&game->entitiesTileset); + ecs_fini(ECS); + ECS = NULL; bzObjectPoolDestroy(game->pools.pathData); bzSpatialGridDestroy(game->entityGrid); - - ecs_singleton_remove(ECS, Game); } diff --git a/game/systems.h b/game/systems.h index 4d7cd99..890992f 100644 --- a/game/systems.h +++ b/game/systems.h @@ -10,23 +10,39 @@ * Entity Systems **********************************/ -/* - * 0: Game (singleton) - */ -void entityRemoved(ecs_iter_t *it); -/* - * 0: Game (singleton) - */ -void entityAdded(ecs_iter_t *it); - -/* +/* Observer (for unregistering collision) * 0: Game (singleton) * 1: Position - * 2: Size - * 3: MoveForce - * 4: SpatialGridID + * 3: SpatialGridID */ -void entityUpdatePhysics(ecs_iter_t *it); +void entitySpatialRemoved(ecs_iter_t *it); + +/* Observer (for releasing path objects) + * 0: Game (singleton)l for object pool + * 1: Path + */ +void pathRemoved(ecs_iter_t *it); + + +/* + * 0: Game (singleton) for collisions + * 1: Position + * 2: Rotation + * 3: Velocity + * 4: AngularVelocity + * 5: SteeringOutput + */ +void entityUpdateKinematic(ecs_iter_t *it); + +/* + * 1: Position + * 2: Rotation + * 3: Velocity + * 4: AngularVelocity + * 5: SteeringOutput + * 6: Path + */ +void entityFollowPath(ecs_iter_t *it); /* * 0: @@ -41,13 +57,9 @@ void renderEntities(ecs_iter_t *it); */ void renderColliders(ecs_iter_t *it); -//void renderEntities(ecs_iter_t *it); -void updateAnimations(ecs_iter_t *it); -void updatePos(ecs_iter_t *it); -void targetFinish(ecs_iter_t *it); -void startPath(ecs_iter_t *it); -void drawDebugPath(ecs_iter_t *it); - -void uiTask(ecs_iter_t *it); +/* + * 1: Path + */ +void renderDebugPath(ecs_iter_t *it); #endif //PIXELDEFENSE_SYSTEMS_H diff --git a/game/systems_entity.c b/game/systems_entity.c index 21f1b74..5730be3 100644 --- a/game/systems_entity.c +++ b/game/systems_entity.c @@ -5,30 +5,53 @@ #include #include -void entityRemoved(ecs_iter_t *it) { - +static Position getBottomLeftPos(Position pos, Size size) { + return (Position) {pos.x - size.x * 0.5f, pos.y - size.y * 0.5f}; } -void entityAdded(ecs_iter_t *it) { -} -void entityUpdatePhysics(ecs_iter_t *it) { +void entitySpatialRemoved(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); + SpatialGridID *spatialID = ecs_field(it, SpatialGridID , 2); 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]); - f32 posX = pos[i].x - size[i].x * 0.5f; - f32 posY = pos[i].y - size[i].y * 0.5f; - bzSpatialGridUpdate(game->entityGrid, spatialID[i], posX, posY, size[i].x, size[i].y); + bzSpatialGridRemove(game->entityGrid, spatialID[i]); } } +void pathRemoved(ecs_iter_t *it) { + Game *game = ecs_singleton_get_mut(ECS, Game); + BzObjectPool *pool = game->pools.pathData; + Path *path = ecs_field(it, Path, 1); + + for (i32 i = 0; i < it->count; i++) { + PathData *cur = path[i].paths; + while (cur) { + bzObjectPoolRelease(pool, cur); + cur = cur->next; + } + } +} + +void entityUpdateKinematic(ecs_iter_t *it) { + Position *pos = ecs_field(it, Position, 1); + Rotation *rotation = ecs_field(it, Rotation, 2); + Velocity *velocity = ecs_field(it, Velocity, 3); + AngularVelocity *angularVelocity = ecs_field(it, Rotation, 4); + SteeringOutput *steeringOutput = ecs_field(it, SteeringOutput, 5); +} + +void entityFollowPath(ecs_iter_t *it) { + Position *pos = ecs_field(it, Position, 1); + Rotation *rotation = ecs_field(it, Rotation, 2); + Velocity *velocity = ecs_field(it, Velocity, 3); + AngularVelocity *angularVelocity = ecs_field(it, Rotation, 4); + SteeringOutput *steeringOutput = ecs_field(it, SteeringOutput, 5); + Path *path = ecs_field(it, Path, 6); + +} + void updateAnimations(ecs_iter_t *it) { Game *game = ecs_singleton_get_mut(ECS, Game); Animation *anim = ecs_field(it, Animation, 1); @@ -66,9 +89,11 @@ static void render(ecs_iter_t *it) { void renderTerrain(ecs_iter_t *it) { render(it); } + void renderBuildings(ecs_iter_t *it) { render(it); } + void renderEntities(ecs_iter_t *it) { render(it); } @@ -84,68 +109,8 @@ void renderColliders(ecs_iter_t *it) { } } -void updatePos(ecs_iter_t *it) { - Position *pos = ecs_field(it, Position, 1); - TargetPosition *target = ecs_field(it, TargetPosition, 2); - TextureRegion *t = ecs_field(it, TextureRegion, 3); - for (i32 i = 0; i < it->count; i++) { - Vector2 d = Vector2Subtract(target[i], pos[i]); - if (Vector2LengthSqr(d) < 1) { - ecs_remove(ECS, it->entities[i], TargetPosition); - } - - Vector2 dN = Vector2Normalize(d); - - dN = Vector2Scale(dN, 20); - t[i].flipX = dN.x < 0; - - - pos[i].x += dN.x * it->delta_time; - pos[i].y += dN.y * it->delta_time; - - } -} -#include -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]; - Path *path = ecs_get_mut(it->world, e, Path); - if (path->curWaypoint >= path->paths->numWaypoints) { - PathData *finished = path->paths; - path->paths = finished->next; - path->curWaypoint = 0; - bzObjectPoolRelease(game->pools.pathData, finished); - // Finished - if (path->paths == NULL) { - ecs_remove(it->world, e, Path); - continue; - } - } - TargetPosition target = path->paths->waypoints[path->curWaypoint]; - path->curWaypoint++; - target.x += rand() % (4 + 1 + 2) -2; - ecs_set(it->world, e, TargetPosition, {target.x, target.y}); - } - -} -void startPath(ecs_iter_t *it) { - Path *path = ecs_field(it, Path, 1); - - for (i32 i = 0; i < it->count; i++) { - ecs_entity_t e = it->entities[i]; - if (path->paths == NULL) { - ecs_remove(it->world, e, Path); - continue; - } - ecs_set(it->world, e, TargetPosition, {path[i].paths->waypoints[0].x, path[i].paths->waypoints[0].y}); - path[i].curWaypoint = 1; - } -} -void drawDebugPath(ecs_iter_t *it) { +void renderDebugPath(ecs_iter_t *it) { Path *path = ecs_field(it, Path, 1); for (i32 i = 0; i < it->count; i++) {