DEADSOFTWARE

Добавлена стрельба
[netwar.git] / game.c
1 #include <SDL2/SDL.h>
3 #include <assert.h>
4 #include <stdbool.h>
5 #include <math.h>
7 #include "game.h"
9 #define SPEED 0.00006
10 #define ROTATE 0.00004
11 #define BULL_SPEED 0.008
13 Player g_player[MAX_PLAYERS];
14 Bullet g_bullet[MAX_BULLETS];
16 void g_player_set(unsigned int id, bool live, float x, float y, float r, float vx, float vy, float vr) {
17 assert(id < MAX_PLAYERS);
18 g_player[id] = (Player) {
19 .updated = true,
20 .live = live,
21 .x = x,
22 .y = y,
23 .r = r,
24 .vx = vx,
25 .vy = vy,
26 .vr = vr,
27 };
28 }
30 void g_bullet_set(unsigned int id, unsigned int owner, bool live, float x, float y, float vx, float vy, int tick) {
31 assert(id < MAX_BULLETS);
32 assert(owner < MAX_PLAYERS);
33 g_bullet[id] = (Bullet) {
34 .live = live,
35 .owner = owner,
36 .x = x,
37 .y = y,
38 .vx = vx,
39 .vy = vy,
40 .tick = tick,
41 };
42 }
44 static int freebullet() {
45 for(int i = 0; i < MAX_BULLETS; i++)
46 if(!g_bullet[i].live)
47 return i;
48 return -1;
49 }
51 static void moveplayer(int id, float speed) {
52 g_player[id].vx += speed * cos(g_player[id].r * 2 * M_PI);
53 g_player[id].vy += speed * sin(g_player[id].r * 2 * M_PI);
54 }
56 static void roteplayer(int id, float speed) {
57 g_player[id].vr += speed;
58 }
60 static void fireplayer(int id) {
61 int j = freebullet();
62 if(j < 0)
63 return;
65 float vx = BULL_SPEED * cos(g_player[id].r * 2 * M_PI);
66 float vy = BULL_SPEED * sin(g_player[id].r * 2 * M_PI);
67 g_bullet_set(j, id, true, g_player[id].x, g_player[id].y, vx, vy, 0);
68 }
70 static void checkspacebound(float * a) {
71 float x = *a;
72 if(x < -1)
73 x = fabs(x);
74 else if(x > 1)
75 x = -x;
76 *a = x;
77 }
79 static bool collide(float x1, float y1, float r1, float x2, float y2, float r2) {
80 float l = sqrtf(powf(x1 - x2, 2) + powf(y1 - y2, 2));
81 return ((l - r1 - r2) <= 0);
82 }
84 void g_player_does(unsigned int id, DoesCode code) {
85 assert(id < MAX_PLAYERS);
86 g_player[id].updated = true;
87 switch(code) {
88 case DOES_UP: moveplayer(id, SPEED); break;
89 case DOES_DOWN: moveplayer(id, -SPEED); break;
90 case DOES_LEFT: roteplayer(id, -ROTATE); break;
91 case DOES_RIGHT: roteplayer(id, ROTATE); break;
92 case DOES_FIRE: fireplayer(id); break;
93 }
94 }
96 void g_update() {
97 for(int i = 0; i < MAX_PLAYERS; i++) {
98 if(g_player[i].live) {
99 g_player[i].updated = true;
100 g_player[i].x += g_player[i].vx;
101 g_player[i].y += g_player[i].vy;
102 g_player[i].r += g_player[i].vr;
103 checkspacebound(&g_player[i].x);
104 checkspacebound(&g_player[i].y);
108 for(int i = 0; i < MAX_BULLETS; i++) {
109 if(g_bullet[i].live) {
110 g_bullet[i].updated = true;
111 g_bullet[i].tick += 1;
112 g_bullet[i].x += g_bullet[i].vx;
113 g_bullet[i].y += g_bullet[i].vy;
115 checkspacebound(&g_bullet[i].x);
116 checkspacebound(&g_bullet[i].y);
118 for(int j = 0; j < MAX_PLAYERS; j++)
119 if(g_player[j].live)
120 if(collide(g_bullet[i].x, g_bullet[i].y, 0.0001, g_player[j].x, g_player[j].y, PLAYER_SIZE))
121 if(j != g_bullet[i].owner)
122 g_player[j].live = false;
124 if(g_bullet[i].tick > BULLET_TIME)
125 g_bullet[i].live = false;