diff options
| -rw-r--r-- | sdl3_main.c | 418 |
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; +} |
