tonk

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }