tonk.c (4124B)
1 #include <raylib.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <math.h> 5 #include <string.h> 6 #include <sys/param.h> 7 #include <stdbool.h> 8 9 #define TANK_SPEED 100 10 #define TANK_ROT_SPEED 100 11 #define TANK_WIDTH 20 12 #define TANK_HEIGHT 50 13 #define GUN_WIDTH 5 14 #define GUN_HEIGHT 30 15 #define MAX_SHOTS 100 16 17 #define INDEG(rad) (rad * (180 / M_PI)) 18 #define CLAMP(val, lower, upper) ((val < lower) ? lower : ((val > upper) ? upper: val)) 19 20 typedef struct tank { 21 Vector2 pos; 22 float rot, gunrot; 23 } tank; 24 25 typedef struct shot { 26 Vector2 pos; 27 float speed, rot; 28 int bounces; 29 bool exists; 30 tank *shooter; 31 } shot; 32 33 void 34 draw_tank(tank t) { 35 Rectangle tank_body = {t.pos.x, t.pos.y, TANK_WIDTH, TANK_HEIGHT}; 36 Vector2 tank_origin = {TANK_WIDTH / 2, TANK_HEIGHT / 2}; 37 DrawRectanglePro(tank_body, tank_origin, t.rot + 90, DARKGREEN); 38 39 40 41 Rectangle gun_body = { 42 t.pos.x + 5 * cos(t.rot * M_PI / 180), 43 t.pos.y + 5 * sin(t.rot * M_PI / 180), 44 GUN_WIDTH, GUN_HEIGHT}; 45 46 Vector2 gun_origin = {GUN_WIDTH / 2, 0}; 47 DrawRectanglePro(gun_body, gun_origin, t.gunrot + 90, GREEN); 48 49 } 50 51 void 52 draw_shot(shot shot) { 53 DrawCircleV(shot.pos, 3, RED); 54 } 55 56 void 57 update_tank(tank *t, float delta) { 58 float dx = t->pos.x - GetMouseX(), dy = t->pos.y - GetMouseY(); 59 float rads = atan((float)(dy / dx)); 60 if (rads > 0 && dy < 0) rads = rads + M_PI; 61 else if (rads < 0 && dx < 0) rads = rads + M_PI; 62 t->gunrot = INDEG(rads); 63 64 if (IsKeyDown(KEY_D)) 65 t->rot += TANK_ROT_SPEED * delta; 66 if (IsKeyDown(KEY_A)) 67 t->rot -= TANK_ROT_SPEED * delta; 68 69 if (IsKeyDown(KEY_S)) { 70 t->pos.x += (TANK_SPEED * delta) * cos(t->rot * M_PI / 180); 71 t->pos.y += (TANK_SPEED * delta) * sin(t->rot * M_PI / 180); 72 } 73 if (IsKeyDown(KEY_W)) { 74 t->pos.x -= (TANK_SPEED * delta) * cos(t->rot * M_PI / 180); 75 t->pos.y -= (TANK_SPEED * delta) * sin(t->rot * M_PI / 180); 76 } 77 } 78 79 void 80 update_shots(shot *shots, int shot_count, float delta) { 81 for (int i = 0; i < shot_count; i++) { 82 shot *s = &shots[i]; 83 84 if (s->pos.y > GetScreenHeight()) { 85 s->rot = -s->rot; 86 s->pos.y = GetScreenHeight() - 1; 87 s->bounces--; 88 } 89 else if (s->pos.y < 0) { 90 s->rot = -s->rot; 91 s->pos.y = 1; 92 s->bounces--; 93 } 94 if (s->pos.x > GetScreenWidth()) { 95 s->rot = 180-s->rot; 96 s->pos.x = GetScreenWidth() - 1; 97 s->bounces--; 98 } 99 else if (s->pos.x < 0) { 100 s->rot = 180-s->rot; 101 s->pos.x = 1; 102 s->bounces--; 103 } 104 105 if (s->bounces == 0) { 106 s->exists = false; 107 continue; 108 } 109 110 s->pos.x += (s->speed * delta) * cos(s->rot * M_PI / 180); 111 s->pos.y += (s->speed * delta) * sin(s->rot * M_PI / 180); 112 113 while (s->rot > 360) 114 s->rot -= 360; 115 } 116 } 117 118 void 119 append_shot(shot *shots, int shot_count, Vector2 pos, float speed, float rot, int bounces, bool exists, tank *shooter) { 120 shot new = { 121 {(pos.x + GUN_HEIGHT * cos(rot * M_PI / 180)), 122 (pos.y + GUN_HEIGHT * sin(rot * M_PI / 180))}, 123 speed, rot, bounces, exists, shooter}; 124 125 int i; 126 for (i = 0; i < shot_count; i++) { 127 if (!shots[i].exists) 128 break; 129 } 130 131 memcpy(&shots[i], &new, sizeof(shot)); 132 } 133 134 void 135 damage_step(tank *t, shot *shots, int shot_count) { 136 for (int i = 0; i < shot_count; i++) { 137 if (!shots[i].exists || shots[i].shooter == t) continue; 138 int dx = abs((t->pos.x - shots[i].pos.x)), 139 dy = abs((t->pos.y - shots[i].pos.y)); 140 float dist = sqrtf(dx * dx + dy * dy); 141 if (dist < TANK_HEIGHT/2) { 142 printf("HIT\n"); 143 shots[i].exists = false; 144 } 145 } 146 } 147 148 int 149 main() { 150 InitWindow(800, 800, "Tonks!"); 151 //ToggleBorderlessWindowed(); 152 153 tank player = { 154 {400, 400}, 155 0, 156 0 157 }; 158 159 shot *shots = alloca(MAX_SHOTS * sizeof(shot)); 160 memset(shots, 0, MAX_SHOTS * sizeof(shot)); 161 float delta; 162 163 while (!WindowShouldClose()) { 164 delta = GetFrameTime(); 165 BeginDrawing(); 166 ClearBackground(RAYWHITE); 167 168 draw_tank(player); 169 for (int i = 0; i < MAX_SHOTS; i++) { 170 if (shots[i].exists) 171 draw_shot(shots[i]); 172 } 173 EndDrawing(); 174 175 if (IsKeyPressed(KEY_SPACE)) 176 append_shot(shots, MAX_SHOTS, player.pos, 800, player.gunrot + 180, 5, true, &player); 177 178 update_tank(&player, delta); 179 update_shots(shots, MAX_SHOTS, delta); 180 damage_step(&player, shots, MAX_SHOTS); 181 } 182 183 CloseWindow(); 184 }