#include #include #include #include #include #define BULLET_SIZE 2 #define ENTITY_SIZE 16 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 float camera_x, camera_y; 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) { { float plx, ply, minx, miny, maxx, maxy; plx = player.x - camera_x; ply = player.y - camera_y; minx = plx - 80; miny = ply - 80; maxx = plx + 80; maxy = ply + 80; if(minx < 0) camera_x += minx; if(miny < 0) camera_y += miny; if(maxx > 800) camera_x += (maxx - 800); if(maxy > 600) camera_y += (maxy - 600); } 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 - ENTITY_SIZE - camera_x, .y = player.y - 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) continue; SDL_SetRenderDrawColor(renderer, 0xAA, 0xAA, 0xAA, 0xFF); SDL_RenderRect(renderer, &(SDL_FRect){ .x = ghosts[i].x - ENTITY_SIZE - camera_x, .y = ghosts[i].y - 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].x - BULLET_SIZE - camera_x, .y = bullet[i].y - BULLET_SIZE - camera_y, .w = BULLET_SIZE * 2.0, .h = BULLET_SIZE * 2.0 }); } } 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 hs = (ENTITY_SIZE + BULLET_SIZE); float minx = dx - hs; float miny = dy - hs; float maxx = dx + hs; float maxy = dy + hs; 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 + camera_x; shoty = event.button.y + camera_y; break; } } }