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.000006 * TICK_DELAY)
10 #define ROTATE (0.000006 * TICK_DELAY)
11 #define BULL_SPEED (0.0008 * TICK_DELAY)
13 Player g_player[MAX_PLAYERS];
14 Bullet g_bullet[MAX_BULLETS];
16 static bool svmode;
18 void g_player_set(unsigned int id, bool live, float x, float y, float r, float vx, float vy, float vr, int shoot) {
19 assert(id < MAX_PLAYERS);
20 g_player[id] = (Player) {
21 .updated = true,
22 .live = live,
23 .x = x,
24 .y = y,
25 .r = r,
26 .vx = vx,
27 .vy = vy,
28 .vr = vr,
29 };
30 }
32 void g_bullet_set(unsigned int id, unsigned int owner, bool live, float x, float y, float vx, float vy, int tick) {
33 assert(id < MAX_BULLETS);
34 assert(owner < MAX_PLAYERS);
35 g_bullet[id] = (Bullet) {
36 .live = live,
37 .owner = owner,
38 .x = x,
39 .y = y,
40 .vx = vx,
41 .vy = vy,
42 .tick = tick,
43 };
44 }
46 static int freebullet() {
47 for(int i = 0; i < MAX_BULLETS; i++)
48 if(!g_bullet[i].live)
49 return i;
50 return -1;
51 }
53 static void moveplayer(int id, float speed) {
54 g_player[id].vx += speed * cos(g_player[id].r * 2 * M_PI);
55 g_player[id].vy += speed * sin(g_player[id].r * 2 * M_PI);
56 }
58 static void roteplayer(int id, float speed) {
59 g_player[id].vr += speed;
60 }
62 static void fireplayer(int id) {
63 int j = freebullet();
64 if(j < 0)
65 return;
67 if(g_player[id].shoot < PLAYER_SHOOT)
68 return;
70 g_player[id].shoot = 0;
72 if(svmode) {
73 float vx = BULL_SPEED * cos(g_player[id].r * 2 * M_PI);
74 float vy = BULL_SPEED * sin(g_player[id].r * 2 * M_PI);
75 g_bullet_set(j, id, true, g_player[id].x, g_player[id].y, vx, vy, 0);
76 }
77 }
79 static void checkspacebound(float * a) {
80 float x = *a;
81 if(x < -1)
82 x = fabs(x);
83 else if(x > 1)
84 x = -x;
85 *a = x;
86 }
88 static bool collide(float x1, float y1, float r1, float x2, float y2, float r2) {
89 float l = sqrtf(powf(x1 - x2, 2) + powf(y1 - y2, 2));
90 return ((l - r1 - r2) <= 0);
91 }
93 void g_player_does(unsigned int id, DoesBits code) {
94 assert(id < MAX_PLAYERS);
96 if(code.up)
97 moveplayer(id, SPEED);
98 if(code.down)
99 moveplayer(id, -SPEED);
100 if(code.left)
101 roteplayer(id, -ROTATE);
102 if(code.right)
103 roteplayer(id, ROTATE);
104 if(code.fire)
105 fireplayer(id);
108 void g_update() {
109 for(int i = 0; i < MAX_PLAYERS; i++) {
110 if(g_player[i].live) {
111 g_player[i].updated = true;
112 g_player[i].x += g_player[i].vx;
113 g_player[i].y += g_player[i].vy;
114 g_player[i].r += g_player[i].vr;
115 checkspacebound(&g_player[i].x);
116 checkspacebound(&g_player[i].y);
118 ++g_player[i].shoot;
119 if(g_player[i].shoot > PLAYER_SHOOT)
120 g_player[i].shoot = PLAYER_SHOOT;
124 for(int i = 0; i < MAX_BULLETS; i++) {
125 if(g_bullet[i].live) {
126 g_bullet[i].updated = true;
127 g_bullet[i].tick += 1;
128 g_bullet[i].x += g_bullet[i].vx;
129 g_bullet[i].y += g_bullet[i].vy;
131 checkspacebound(&g_bullet[i].x);
132 checkspacebound(&g_bullet[i].y);
134 for(int j = 0; j < MAX_PLAYERS; j++)
135 if(g_player[j].live)
136 if(collide(g_bullet[i].x, g_bullet[i].y, 0.0001, g_player[j].x, g_player[j].y, PLAYER_SIZE))
137 if(j != g_bullet[i].owner)
138 g_player[j].live = false;
140 if(g_bullet[i].tick > BULLET_TIME)
141 g_bullet[i].live = false;
146 void g_init(bool server_mode) {
147 svmode = server_mode;
148 // TODO memset & co