summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoresquizo <esquizo+noreply@esquizo.net>2026-04-29 17:51:33 -0300
committeresquizo <esquizo+noreply@esquizo.net>2026-04-29 17:51:33 -0300
commitd04a27c2e89b3196db2a5873274fbbd4d6e0e102 (patch)
tree38e5c6121d4d60d9e347077512ff965fbf05780b
parent232567e3663a6e9f2d300963b4c3fd46a0b83097 (diff)
sistema idiota de entidades
-rw-r--r--sdl3_main.c418
1 files changed, 243 insertions, 175 deletions
diff --git a/sdl3_main.c b/sdl3_main.c
index 5a4ec6f..28d7c89 100644
--- a/sdl3_main.c
+++ b/sdl3_main.c
@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <SDL3/SDL.h>
+#include <string.h>
#include "dat.h"
@@ -25,18 +26,47 @@ typedef struct {
bool active;
} Bullet;
+typedef struct {
+ enum {
+ EPLAYER,
+ EGHOST,
+ EBULLET,
+ } type;
+
+ bool active;
+ Body body;
+ float time;
+} Entity;
+
+typedef struct {
+ Entity *self;
+ Entity *target;
+} EntityCollision;
+
static void render(void);
static void update(float delta);
static void process_events(void);
+static Entity *allocentity(void);
+static void freeentity(Entity *);
+
+static void entphysics(float delta);
+
+static void enqcoll(EntityCollision *c);
+static void deqcoll(EntityCollision *c);
+
static SDL_Window *window;
static SDL_Renderer *renderer;
static bool running;
static Uint64 old_ticks, new_ticks;
-static Player player = { .body.size = { ENTITY_SIZE, ENTITY_SIZE } };
-static Ghost ghosts[1024];
-static Bullet bullet[1024];
+static Entity *player;
+
+static Entity entitybuffer[2048];
+static int ebufi;
+
+static EntityCollision ecoll[2048];
+static int ecollstart, ecollend, ecollsi;
static float camera_x, camera_y;
@@ -59,12 +89,17 @@ main()
return -1;
}
+ player = allocentity();
+ player->type = EPLAYER;
+ player->body.size[0] = ENTITY_SIZE;
+ player->body.size[1] = ENTITY_SIZE;
for(int i = 0; i < 10; i++) {
- ghosts[i].active = 1;
- ghosts[i].body.pos[0] = rand() % 800;
- ghosts[i].body.pos[1] = rand() % 600;
- ghosts[i].body.size[0] = ENTITY_SIZE;
- ghosts[i].body.size[1] = ENTITY_SIZE;
+ Entity *e = allocentity();
+ e->type = EGHOST;
+ e->body.pos[0] = rand() % 800;
+ e->body.pos[1] = rand() % 600;
+ e->body.size[0] = ENTITY_SIZE;
+ e->body.size[1] = ENTITY_SIZE;
}
running = true;
@@ -93,8 +128,8 @@ render(void)
{
float plx, ply, minx, miny, maxx, maxy;
- plx = player.body.pos[0] - camera_x;
- ply = player.body.pos[1] - camera_y;
+ plx = player->body.pos[0] - camera_x;
+ ply = player->body.pos[1] - camera_y;
minx = plx - 80;
miny = ply - 80;
@@ -131,38 +166,42 @@ render(void)
});
}
- SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
- SDL_RenderRect(renderer, &(SDL_FRect){
- .x = player.body.pos[0] - ENTITY_SIZE - camera_x,
- .y = player.body.pos[1] - ENTITY_SIZE - camera_y,
- .w = ENTITY_SIZE * 2.0,
- .h = ENTITY_SIZE * 2.0
- });
-
- for(int i = 0; i < 1024; i++) {
- if(!ghosts[i].active)
+ for(int i = 0; i < ebufi; i++) {
+ Entity *e = entitybuffer + i;
+ if(!e->active)
continue;
- SDL_SetRenderDrawColor(renderer, 0xAA, 0xAA, 0xAA, 0xFF);
- SDL_RenderRect(renderer, &(SDL_FRect){
- .x = ghosts[i].body.pos[0] - ENTITY_SIZE - camera_x,
- .y = ghosts[i].body.pos[1] - ENTITY_SIZE - camera_y,
- .w = ENTITY_SIZE * 2.0,
- .h = ENTITY_SIZE * 2.0
- });
- }
-
- for(int i = 0; i < 1024; i++) {
- if(!bullet[i].active)
- continue;
-
- SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF);
- SDL_RenderRect(renderer, &(SDL_FRect){
- .x = bullet[i].body.pos[0] - BULLET_SIZE - camera_x,
- .y = bullet[i].body.pos[1] - BULLET_SIZE - camera_y,
- .w = BULLET_SIZE * 2.0,
- .h = BULLET_SIZE * 2.0
- });
+ switch (e->type) {
+ case EPLAYER:
+ SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
+ SDL_RenderRect(renderer, &(SDL_FRect){
+ .x = e->body.pos[0] - ENTITY_SIZE - camera_x,
+ .y = e->body.pos[1] - ENTITY_SIZE - camera_y,
+ .w = ENTITY_SIZE * 2.0,
+ .h = ENTITY_SIZE * 2.0
+ });
+ break;
+
+ case EGHOST:
+ SDL_SetRenderDrawColor(renderer, 0xAA, 0xAA, 0xAA, 0xFF);
+ SDL_RenderRect(renderer, &(SDL_FRect){
+ .x = e->body.pos[0] - ENTITY_SIZE - camera_x,
+ .y = e->body.pos[1] - ENTITY_SIZE - camera_y,
+ .w = ENTITY_SIZE * 2.0,
+ .h = ENTITY_SIZE * 2.0
+ });
+ break;
+
+ case EBULLET:
+ SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF);
+ SDL_RenderRect(renderer, &(SDL_FRect){
+ .x = e->body.pos[0] - BULLET_SIZE - camera_x,
+ .y = e->body.pos[1] - BULLET_SIZE - camera_y,
+ .w = BULLET_SIZE * 2.0,
+ .h = BULLET_SIZE * 2.0
+ });
+ break;
+ }
}
}
@@ -171,122 +210,150 @@ update(float delta)
{
# define SPEED 100
const _Bool *kstate = SDL_GetKeyboardState(NULL);
+ Entity *bullet, *other;
+ float vx, vy;
- player.body.vel[0] = 0;
- player.body.vel[1] = 0;
-
- if(kstate[SDL_SCANCODE_W])
- player.body.vel[1] -= SPEED;
- if(kstate[SDL_SCANCODE_A])
- player.body.vel[0] -= SPEED;
- if(kstate[SDL_SCANCODE_S])
- player.body.vel[1] += SPEED;
- if(kstate[SDL_SCANCODE_D])
- player.body.vel[0] += SPEED;
+ entphysics(delta);
- for(int y = 0; y < map_height; y++)
- for(int x = 0; x < map_width; x++) {
- if(!map_data[x + y * map_width])
- continue;
+ for(int ei = 0; ei < ebufi; ei++) {
+ Entity *e = entitybuffer + ei;
+ if(!e->active)
+ continue;
- Body b = {
- .pos = {
- x * ENTITY_SIZE * 2.0,
- y * ENTITY_SIZE * 2.0,
- },
- .size = { ENTITY_SIZE, ENTITY_SIZE },
- };
-
- if(checkcollision(&player.body, &b)) {
- float p[2];
- resolvecoll(&player.body, &b, p);
-
- for(int i = 0; i < 2; i++)
- player.body.pos[i] -= p[i];
-
- if(p[0] != 0.0) {
- player.body.vel[0] = 0;
- } else {
- player.body.vel[1] = 0;
- }
+ switch(e->type) {
+ case EPLAYER:
+ e->body.vel[0] = 0;
+ e->body.vel[1] = 0;
+
+ if(kstate[SDL_SCANCODE_W])
+ e->body.vel[1] -= SPEED;
+ if(kstate[SDL_SCANCODE_A])
+ e->body.vel[0] -= SPEED;
+ if(kstate[SDL_SCANCODE_S])
+ e->body.vel[1] += SPEED;
+ if(kstate[SDL_SCANCODE_D])
+ e->body.vel[0] += SPEED;
+
+ if(shot) {
+ shot = false;
+ int i;
+
+ float dx = shotx - e->body.pos[0];
+ float dy = shoty - e->body.pos[1];
+ float dd = sqrtf(dx * dx + dy * dy);
+
+ dx /= dd;
+ dy /= dd;
+
+ bullet = allocentity();
+ bullet->type = EBULLET;
+ bullet->time = 0.5;
+ bullet->body.vel[0] = dx * SPEED * 5.0;
+ bullet->body.vel[1] = dy * SPEED * 5.0;
+ bullet->body.pos[0] = e->body.pos[0];
+ bullet->body.pos[1] = e->body.pos[1];
+ bullet->body.size[0] = BULLET_SIZE;
+ bullet->body.size[1] = BULLET_SIZE;
+ bullet->active = true;
}
- }
+ break;
- if(shot) {
- shot = false;
- int i;
+ case EGHOST:
+ vx = 0;
+ vy = 0;
- float dx = shotx - player.body.pos[0];
- float dy = shoty - player.body.pos[1];
- float dd = sqrtf(dx * dx + dy * dy);
+ float dx = player->body.pos[0] - e->body.pos[0];
+ float dy = player->body.pos[1] - e->body.pos[1];
+ float dd = sqrtf(dx * dx + dy * dy);
- dx /= dd;
- dy /= dd;
-
- for(i = 0; i < 1024 && bullet[i].active; i++)
- ;
-
- if(i < 1024) {
- bullet[i].time = 0.5;
- bullet[i].body.vel[0] = dx * SPEED * 5.0;
- bullet[i].body.vel[1] = dy * SPEED * 5.0;
- bullet[i].body.pos[0] = player.body.pos[0];
- bullet[i].body.pos[1] = player.body.pos[1];
- bullet[i].body.size[0] = BULLET_SIZE;
- bullet[i].body.size[1] = BULLET_SIZE;
- bullet[i].active = true;
- }
- }
+ dx /= dd;
+ dy /= dd;
- for(int i = 0; i < 1024; i++) {
- if(!bullet[i].active)
- continue;
+ vx += dx * SPEED;
+ vy += dy * SPEED;
- for(int j = 0; j < 1024; j++) {
- if(!ghosts[j].active)
- continue;
+ for(int j = 0; j < 1024; j++) {
+ other = entitybuffer + j;
+ if(!other->active || other == e)
+ continue;
+
+ float dx = other->body.pos[0] - e->body.pos[0];
+ float dy = other->body.pos[1] - e->body.pos[1];
+ float dd = sqrtf(dx * dx + dy * dy);
- int r = checkcollision(&bullet[i].body, &ghosts[j].body);
-
- if(r) {
- ghosts[j].active = false;
- bullet[i].active = false;
+ dx /= dd;
+ dy /= dd;
+
+ if(dd < 40) {
+ vx -= dx * 100;
+ vy -= dy * 100;
+ }
}
+
+ e->body.vel[0] = vx;
+ e->body.vel[1] = vy;
+ break;
+ case EBULLET:
+ break;
}
}
+}
- for(int i = 0; i < 1024; i++) {
- if(!ghosts[i].active)
- continue;
+void
+process_events()
+{
+ SDL_Event event;
- float vx = 0, vy = 0;
+ while(SDL_PollEvent(&event)) {
+ switch(event.type) {
+ case SDL_EVENT_QUIT:
+ running = false;
+ break;
+ case SDL_EVENT_MOUSE_BUTTON_DOWN:
+ shot = true;
+ shotx = event.button.x + camera_x;
+ shoty = event.button.y + camera_y;
+ break;
+ }
+ }
+}
- float dx = player.body.pos[0] - ghosts[i].body.pos[0];
- float dy = player.body.pos[1] - ghosts[i].body.pos[1];
- float dd = sqrtf(dx * dx + dy * dy);
+Entity *
+allocentity(void)
+{
+ Entity *e;
- dx /= dd;
- dy /= dd;
+ for(e = entitybuffer; e < entitybuffer + ebufi; e++) {
+ if(!e->active)
+ break;
+ }
- vx += dx * SPEED;
- vy += dy * SPEED;
+ if(e >= entitybuffer + ebufi) {
+ if(ebufi >= 2048)
+ return NULL;
+ e = entitybuffer + ebufi;
+ ebufi++;
+ }
- for(int j = 0; j < 1024; j++) {
- if(!ghosts[j].active || i == j)
- continue;
+ memset(e, 0, sizeof(*e));
+ e->active = true;
- float dx = ghosts[j].body.pos[0] - ghosts[i].body.pos[0];
- float dy = ghosts[j].body.pos[1] - ghosts[i].body.pos[1];
- float dd = sqrtf(dx * dx + dy * dy);
+ return e;
+}
- dx /= dd;
- dy /= dd;
+void
+freeentity(Entity *e)
+{
+ e->active = false;
+}
- if(dd < 40) {
- vx -= dx * 100;
- vy -= dy * 100;
- }
- }
+void
+entphysics(float delta)
+{
+ for(int i = 0; i < ebufi; i++) {
+ Entity *e = entitybuffer + i;
+ if(!e->active)
+ break;
for(int y = 0; y < map_height; y++)
for(int x = 0; x < map_width; x++) {
@@ -301,68 +368,69 @@ update(float delta)
.size = { ENTITY_SIZE, ENTITY_SIZE },
};
- if(checkcollision(&ghosts[i].body, &b)) {
+ if(checkcollision(&e->body, &b)) {
float p[2];
- resolvecoll(&ghosts[i].body, &b, p);
+ resolvecoll(&e->body, &b, p);
for(int i = 0; i < 2; i++)
- ghosts[i].body.pos[i] -= p[i];
+ e->body.pos[i] -= p[i];
if(p[0] != 0.0) {
- vx = 0;
+ e->body.vel[0] = 0;
} else {
- vy = 0;
+ e->body.vel[1] = 0;
}
}
}
- ghosts[i].body.vel[0] = vx;
- ghosts[i].body.vel[1] = vy;
- }
+ for(int j = i; j < ebufi; j++) {
+ Entity *f = entitybuffer + j;
+ if(!f->active)
+ break;
- player.body.pos[0] += player.body.vel[0] * delta;
- player.body.pos[1] += player.body.vel[1] * delta;
+ if(checkcollision(&e->body, &f->body)) {
+ EntityCollision cl;
- for(int i = 0; i < 1024; i++) {
- if(!ghosts[i].active)
- continue;
-
- ghosts[i].body.pos[0] += ghosts[i].body.vel[0] * delta;
- ghosts[i].body.pos[1] += ghosts[i].body.vel[1] * delta;
- }
+ cl.self = e;
+ cl.target = f;
- for(int i = 0; i < 1024; i++) {
- if(!bullet[i].active)
- continue;
-
- bullet[i].time -= delta;
- if(bullet[i].time <= 0.0) {
- bullet[i].active = false;
- continue;
+ enqcoll(&cl);
+ }
}
+ }
+
+ for(int i = 0; i < ebufi; i++) {
+ Entity *e = entitybuffer + i;
+ if(!e->active)
+ break;
- bullet[i].body.pos[0] += delta * bullet[i].body.vel[0];
- bullet[i].body.pos[1] += delta * bullet[i].body.vel[1];
+ for(int j = 0; j < 2; j++)
+ e->body.pos[j] += e->body.vel[j] * delta;
}
}
void
-process_events()
+enqcoll(EntityCollision *c)
{
- SDL_Event event;
+ if(ecollsi >= 2048)
+ return;
- while(SDL_PollEvent(&event)) {
- switch(event.type) {
- case SDL_EVENT_QUIT:
- running = false;
- break;
- case SDL_EVENT_MOUSE_BUTTON_DOWN:
- shot = true;
- shotx = event.button.x + camera_x;
- shoty = event.button.y + camera_y;
- break;
- }
- }
+ ecollsi++;
+
+ ecoll[ecollend++] = *c;
+ if(ecollend >= 2048)
+ ecollend = 0;
}
+void
+deqcoll(EntityCollision *c)
+{
+ if(ecollsi <= 0)
+ return;
+
+ ecollsi--;
+ ecoll[ecollstart++] = *c;
+ if(ecollstart >= 2048)
+ ecollstart = 0;
+}