#define BECS_MAX_ENTITIES 100000 #define BECS_MAX_COMPONENTS 4 #define BECS_IMPLEMENTATION #include "../../becs.h" #include #include #include "external/raylib/src/raylib.h" // Component structs typedef struct { float x, y; } Position; typedef struct { float vx, vy; } Velocity; typedef struct { float ax, ay; } Acceleration; typedef struct { float radius; float lifetime; } ParticleData; // Function to spawn a particle void SpawnParticle(BECS_ECS *ecs, BECS_ComponentID posID, BECS_ComponentID velID, BECS_ComponentID accID, BECS_ComponentID dataID, float x, float y) { BECS_Entity entity = BECS_EntityCreate(ecs); if (entity == BECS_NULL_ENTITY) return; Position *pos = (Position *)BECS_ComponentAdd(ecs, entity, posID); pos->x = x; pos->y = y; Velocity *vel = (Velocity *)BECS_ComponentAdd(ecs, entity, velID); vel->vx = GetRandomValue(-100, 100); vel->vy = GetRandomValue(-200, -50); Acceleration *acc = (Acceleration *)BECS_ComponentAdd(ecs, entity, accID); acc->ax = 0.0f; acc->ay = 100.0f; // Gravity ParticleData *data = (ParticleData *)BECS_ComponentAdd(ecs, entity, dataID); data->radius = 5.0f; data->lifetime = 2.0f; } int main(void) { // Initialize ECS size_t componentSizes[4] = {sizeof(Position), sizeof(Velocity), sizeof(Acceleration), sizeof(ParticleData)}; size_t memSize = BECS_GetMinMemoryArenaSize(componentSizes, 4); printf("%lu\n", memSize); char *memory = (char *)malloc(memSize); BECS_ECS ecs = BECS_InitECS(memory, memSize); // Register components BECS_ComponentID posID = BECS_ComponentRegister(&ecs, sizeof(Position), BECS_MAX_ENTITIES); BECS_ComponentID velID = BECS_ComponentRegister(&ecs, sizeof(Velocity), BECS_MAX_ENTITIES); BECS_ComponentID accID = BECS_ComponentRegister(&ecs, sizeof(Acceleration), BECS_MAX_ENTITIES); BECS_ComponentID dataID = BECS_ComponentRegister(&ecs, sizeof(ParticleData), BECS_MAX_ENTITIES); InitWindow(1600, 800, "2D Particle System with BECS"); while (!WindowShouldClose()) { float dt = GetFrameTime(); // Update lifetimes and despawn for (BECS_Entity entity = 0; entity < BECS_MAX_ENTITIES; entity++) { if (!BECS_IsEntityAlive(&ecs, entity)) continue; if (BECS_ComponentHas(&ecs, entity, dataID)) { ParticleData *data = (ParticleData *)BECS_ComponentGet(&ecs, entity, dataID); data->lifetime -= dt; if (data->lifetime <= 0.0f) { BECS_EntityDestroy(&ecs, entity); } } } // Spawn particle on mouse click if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) { Vector2 mousePos = GetMousePosition(); for (uint32_t i = 0; i < 10; i++) { SpawnParticle(&ecs, posID, velID, accID, dataID, mousePos.x, mousePos.y); } } // Physics system: update position and velocity for (BECS_Entity entity = 0; entity < BECS_MAX_ENTITIES; entity++) { if (!BECS_IsEntityAlive(&ecs, entity)) continue; if (BECS_ComponentHas(&ecs, entity, posID) && BECS_ComponentHas(&ecs, entity, velID) && BECS_ComponentHas(&ecs, entity, accID)) { Position *pos = (Position *)BECS_ComponentGet(&ecs, entity, posID); Velocity *vel = (Velocity *)BECS_ComponentGet(&ecs, entity, velID); Acceleration *acc = (Acceleration *)BECS_ComponentGet(&ecs, entity, accID); vel->vx += acc->ax * dt; vel->vy += acc->ay * dt; pos->x += vel->vx * dt; pos->y += vel->vy * dt; } } BeginDrawing(); ClearBackground(BLACK); // Render system: draw particles for (BECS_Entity entity = 0; entity < BECS_MAX_ENTITIES; entity++) { if (!BECS_IsEntityAlive(&ecs, entity)) continue; if (BECS_ComponentHas(&ecs, entity, posID) && BECS_ComponentHas(&ecs, entity, dataID)) { Position *pos = (Position *)BECS_ComponentGet(&ecs, entity, posID); ParticleData *data = (ParticleData *)BECS_ComponentGet(&ecs, entity, dataID); float alpha = data->lifetime / 2.0f; Color color = {255, 255, 255, (unsigned char)(alpha * 255)}; DrawCircle((int)pos->x, (int)pos->y, data->radius, color); } } DrawText(TextFormat("Particles: %u", ecs.entityCount), 10, 10, 20, WHITE); EndDrawing(); } CloseWindow(); free(memory); return 0; }