#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; } void LifetimeSystem(BECS_ECS *ecs, float dt) { ParticleData *data = (ParticleData *)ecs->componentPools[3].denseArray; BECS_Entity *entity = (BECS_Entity *)ecs->componentPools[3].denseEntityMapping; for (uint32_t i = 0; i < ecs->entityCount; i++) { data[i].lifetime -= dt; if (data[i].lifetime <= 0.0f) { BECS_EntityDestroy(ecs, entity[i]); } } } void PhysicsSystem(BECS_ECS *ecs, float dt) { Position *pos = ((Position *)ecs->componentPools[0].denseArray); Velocity *vel = ((Velocity *)ecs->componentPools[1].denseArray); Acceleration *acc = ((Acceleration *)ecs->componentPools[2].denseArray); for (uint32_t i = 0; i < ecs->entityCount; i++) { vel[i].vy += acc[i].ay * dt; vel[i].vx += acc[i].ax * dt; pos[i].y += vel[i].vy * dt; pos[i].x += vel[i].vx * dt; } } void RenderSystem(BECS_ECS *ecs, float dt) { Position *pos = ((Position *)ecs->componentPools[0].denseArray); ParticleData *data = ((ParticleData *)ecs->componentPools[3].denseArray); for (uint32_t i = 0; i < ecs->entityCount; i++) { float alpha = data[i].lifetime / 2.0; Color color = {255, 255, 255, (unsigned char)(alpha * 255)}; DrawCircle(pos[i].x, pos[i].y, data[i].radius, color); } } 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); // } // } // } LifetimeSystem(&ecs, dt); // Spawn particle on mouse click if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) { Vector2 mousePos = GetMousePosition(); for (uint32_t i = 0; i < 10000; 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; // } // } PhysicsSystem(&ecs, 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); // } // } RenderSystem(&ecs, dt); DrawText(TextFormat("Particles: %u", ecs.entityCount), 10, 10, 20, WHITE); EndDrawing(); } CloseWindow(); free(memory); return 0; }