summaryrefslogtreecommitdiff
path: root/sdl3_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sdl3_main.c')
-rw-r--r--sdl3_main.c265
1 files changed, 265 insertions, 0 deletions
diff --git a/sdl3_main.c b/sdl3_main.c
new file mode 100644
index 0000000..1a20d15
--- /dev/null
+++ b/sdl3_main.c
@@ -0,0 +1,265 @@
+#include <SDL3/SDL_rect.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <SDL3/SDL.h>
+
+static void render(void);
+static void update(float delta);
+static void process_events(void);
+
+typedef struct {
+ float x, y;
+} Player;
+
+typedef struct {
+ float x, y;
+ float vx, vy;
+ bool active;
+} Ghost;
+
+typedef struct {
+ float x, y;
+ float vx, vy;
+ float time;
+ bool active;
+} Bullet;
+
+static SDL_Window *window;
+static SDL_Renderer *renderer;
+static bool running;
+static Uint64 old_ticks, new_ticks;
+
+static Player player;
+static Ghost ghosts[1024];
+static Bullet bullet[1024];
+
+static bool shot;
+static int shotx, shoty;
+
+int
+main()
+{
+ if(!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
+ fprintf(stderr, "SDL_Init(): %s\n", SDL_GetError());
+ return 1;
+ }
+
+ if(!SDL_CreateWindowAndRenderer("window", 800, 600, SDL_WINDOW_OPENGL, &window, &renderer)) {
+ fprintf(stderr, "SDL_CreateWindowAndRenderer: %s\n", SDL_GetError());
+ return -1;
+ }
+
+ for(int i = 0; i < 10; i++) {
+ ghosts[i].active = 1;
+ ghosts[i].x = rand() % 800;
+ ghosts[i].y = rand() % 600;
+ }
+
+ running = true;
+ old_ticks = SDL_GetTicksNS();
+ while(running) {
+ double delta;
+ process_events();
+
+ new_ticks = SDL_GetTicksNS();
+ delta = (new_ticks - old_ticks) / 1000000000.0;
+ old_ticks = new_ticks;
+ update(delta);
+
+ render();
+ SDL_RenderPresent(renderer);
+ }
+
+ SDL_DestroyWindow(window);
+ SDL_Quit();
+ return 0;
+}
+
+void
+render(void)
+{
+ SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
+ SDL_RenderClear(renderer);
+
+ SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
+ SDL_RenderRect(renderer, &(SDL_FRect){
+ .x = player.x - 15,
+ .y = player.y - 15,
+ .w = 30,
+ .h = 30
+ });
+
+ for(int i = 0; i < 1024; i++) {
+ if(!ghosts[i].active)
+ continue;
+
+ SDL_SetRenderDrawColor(renderer, 0xAA, 0xAA, 0xAA, 0xFF);
+ SDL_RenderRect(renderer, &(SDL_FRect){
+ .x = ghosts[i].x - 15,
+ .y = ghosts[i].y - 15,
+ .w = 30,
+ .h = 30
+ });
+ }
+
+ 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].x - 2,
+ .y = bullet[i].y - 2,
+ .w = 4,
+ .h = 4
+ });
+ }
+}
+
+void
+update(float delta)
+{
+# define SPEED 100
+ const _Bool *kstate = SDL_GetKeyboardState(NULL);
+
+ if(kstate[SDL_SCANCODE_W])
+ player.y -= delta * SPEED;
+ if(kstate[SDL_SCANCODE_A])
+ player.x -= delta * SPEED;
+ if(kstate[SDL_SCANCODE_S])
+ player.y += delta * SPEED;
+ if(kstate[SDL_SCANCODE_D])
+ player.x += delta * SPEED;
+
+ if(shot) {
+ shot = false;
+ int i;
+
+ float dx = shotx - player.x;
+ float dy = shoty - player.y;
+ 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].vx = dx * SPEED * 5.0;
+ bullet[i].vy = dy * SPEED * 5.0;
+ bullet[i].x = player.x;
+ bullet[i].y = player.y;
+ bullet[i].active = true;
+ }
+ }
+
+ for(int i = 0; i < 1024; i++) {
+ if(!bullet[i].active)
+ continue;
+
+ for(int j = 0; j < 1024; j++) {
+ if(!ghosts[j].active)
+ continue;
+
+ float dx = bullet[i].x - ghosts[j].x;
+ float dy = bullet[i].y - ghosts[j].y;
+
+ float minx = dx - 17;
+ float miny = dy - 17;
+ float maxx = dx + 17;
+ float maxy = dy + 17;
+
+ bool contains_x = minx < 0 && maxx > 0;
+ bool contains_y = miny < 0 && maxy > 0;
+
+ if(contains_x && contains_y) {
+ ghosts[j].active = false;
+ bullet[i].active = false;
+ }
+ }
+ }
+
+ for(int i = 0; i < 1024; i++) {
+ if(!ghosts[i].active)
+ continue;
+
+ float vx = 0, vy = 0;
+
+ float dx = player.x - ghosts[i].x;
+ float dy = player.y - ghosts[i].y;
+ float dd = sqrtf(dx * dx + dy * dy);
+
+ dx /= dd;
+ dy /= dd;
+
+ vx += dx * SPEED;
+ vy += dy * SPEED;
+
+ for(int j = 0; j < 1024; j++) {
+ if(!ghosts[j].active || i == j)
+ continue;
+
+ float dx = ghosts[j].x - ghosts[i].x;
+ float dy = ghosts[j].y - ghosts[i].y;
+ float dd = sqrtf(dx * dx + dy * dy);
+
+ dx /= dd;
+ dy /= dd;
+
+ if(dd < 40) {
+ vx -= dx * 100;
+ vy -= dy * 100;
+ }
+ }
+
+ ghosts[i].vx = vx;
+ ghosts[i].vy = vy;
+ }
+
+ for(int i = 0; i < 1024; i++) {
+ if(!ghosts[i].active)
+ continue;
+
+ ghosts[i].x += ghosts[i].vx * delta;
+ ghosts[i].y += ghosts[i].vy * delta;
+ }
+
+ 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;
+ }
+
+ bullet[i].x += delta * bullet[i].vx;
+ bullet[i].y += delta * bullet[i].vy;
+ }
+}
+void
+process_events()
+{
+ SDL_Event event;
+
+ 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;
+ shoty = event.button.y;
+ break;
+ }
+ }
+}
+
+