#define MAX_SPEED (0.3 / TICK)
#define MAX_ROTATE (0.3 / TICK)
+// Цифры взяты с потолка, но вроде неплохо подобраны
+#define G 3.673e-4
+#define M_STAR 10.0
+#define M_SHIP 0.1
+
Player g_player[MAX_PLAYERS];
Bullet g_bullet[MAX_BULLETS];
*a = x;
}
+static float length(float x1, float y1, float x2, float y2) {
+ return sqrtf(powf(x1 - x2, 2) + powf(y1 - y2, 2));
+}
+
static bool collide(float x1, float y1, float r1, float x2, float y2, float r2) {
- float l = sqrtf(powf(x1 - x2, 2) + powf(y1 - y2, 2));
- return ((l - r1 - r2) <= 0);
+ return ((length(x1, y1, x2, y2) - r1 - r2) <= 0);
+}
+
+static void gravity(float * vx, float * vy, float x, float y) {
+ *vx += copysign(G * M_STAR * M_SHIP / length(0, 0, x, y), x * -1);
+ *vy += copysign(G * M_STAR * M_SHIP / length(0, 0, x, y), y * -1);
}
void g_player_does(unsigned int id, DoesBits code) {
g_player[i].x += g_player[i].vx;
g_player[i].y += g_player[i].vy;
g_player[i].r += g_player[i].vr;
+
+ gravity(&g_player[i].vx, &g_player[i].vy, g_player[i].x, g_player[i].y);
+
checkspacebound(&g_player[i].x);
checkspacebound(&g_player[i].y);
++g_player[i].shoot;
if(g_player[i].shoot > PLAYER_SHOOT)
g_player[i].shoot = PLAYER_SHOOT;
+
+ if(collide(g_player[i].x, g_player[i].y, PLAYER_SIZE, 0, 0, STAR_SIZE))
+ g_player[i].live = false;
}
}
#define HEIGHT 480
static const float ship[] = {
- +1.0, +0.0, -1.0, -1.0,
- -1.0, -1.0, +0.0, +0.0,
- +0.0, +0.0, -1.0, +1.0,
- -1.0, +1.0, +1.0, +0.0,
+ +1.0, +0.0,
+ -1.0, -1.0,
+ +0.0, +0.0,
+ -1.0, +1.0,
+ +1.0, +0.0,
+};
+
+static const float star[] = {
+ +1.0, +0.0,
+ +0.0, -1.0,
+ -1.0, +0.0,
+ +0.0, +1.0,
+ +1.0, +0.0,
};
static char * host = "localhost";
SDL_DestroyWindow(window);
}
+static void paintmodel(const float * model, int modelsz, float mx, float my, float r, float size, int cx, int cy) {
+ int scale = (WIDTH + HEIGHT) / 2 * size;
+
+ int count = modelsz / sizeof(model[0]) / 2;
+ int x = mx * WIDTH / 2;
+ int y = my * HEIGHT / 2;
+
+ SDL_Point pix[count];
+ for(int j = 0; j < count * 2; j += 2) {
+ float c = cos(r * 2 * M_PI);
+ float s = sin(r * 2 * M_PI);
+ float rx = model[j + 0] * scale;
+ float ry = model[j + 1] * scale;
+ pix[j / 2].x = cx + x + (c * rx - s * ry);
+ pix[j / 2].y = cy + y + (s * rx + c * ry);
+ }
+
+ SDL_RenderDrawLines(renderer, pix, count);
+}
+
static void paintwindow() {
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
SDL_RenderClear(renderer);
int cx = WIDTH / 2;
int cy = HEIGHT / 2;
- int shipsz = (WIDTH + HEIGHT) / 2 * PLAYER_SIZE;
+
+ SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0xFF, 0x00);
+ paintmodel(star, sizeof(star), 0, 0, 0, STAR_SIZE, cx, cy);
for(int i = 0; i < MAX_PLAYERS; i++) {
if(i == cl_playerid)
else
SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0x00);
- int count = sizeof(ship) / sizeof(ship[0]) / 2;
- int x = g_player[i].x * WIDTH / 2;
- int y = g_player[i].y * HEIGHT / 2;
-
- SDL_Point pixship[count];
- for(int j = 0; j < count * 2; j += 2) {
- float c = cos(g_player[i].r * 2 * M_PI);
- float s = sin(g_player[i].r * 2 * M_PI);
- float rx = ship[j + 0] * shipsz;
- float ry = ship[j + 1] * shipsz;
- pixship[j / 2].x = cx + x + (c * rx - s * ry);
- pixship[j / 2].y = cy + y + (s * rx + c * ry);
- }
-
if(g_player[i].live)
- SDL_RenderDrawLines(renderer, pixship, count);
+ paintmodel(ship, sizeof(ship), g_player[i].x, g_player[i].y, g_player[i].r, PLAYER_SIZE, cx, cy);
}
for(int i = 0; i < MAX_BULLETS; i++) {