added points, sync still missing
This commit is contained in:
parent
5112241a93
commit
6fc4e795d2
149
src/game.cpp
149
src/game.cpp
@ -2,6 +2,14 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "MersenneTwister.h"
|
||||
|
||||
double rand2() {
|
||||
float u = (float) rand() / (float) RAND_MAX;
|
||||
return 2.0 * (u - 0.5);
|
||||
}
|
||||
|
||||
void game_setup_team(team_t *team, uint8_t id) {
|
||||
team->id = id;
|
||||
@ -13,6 +21,9 @@ void game_setup_team(team_t *team, uint8_t id) {
|
||||
team->x = 2000.0 * (id & (1 << 0));
|
||||
team->y = 2000.0 * (id & (1 << 1));
|
||||
team->z = 2000.0 * (id & (1 << 2));
|
||||
|
||||
team->points = 0;
|
||||
team->wins = 0;
|
||||
}
|
||||
|
||||
void game_setup_player(player_t *player) {
|
||||
@ -21,16 +32,74 @@ void game_setup_player(player_t *player) {
|
||||
player->team = NULL;
|
||||
}
|
||||
|
||||
void game_setup(game_t *game) {
|
||||
size_t i;
|
||||
void game_setup_point(point_t *point) {
|
||||
point->status = 1;
|
||||
point->x = 1000 + 500.0 * rand2();
|
||||
point->y = 500.0 * rand2();
|
||||
point->z = 500.0 * rand2();
|
||||
}
|
||||
|
||||
void game_reset_team(team_t *team, uint8_t id) {
|
||||
team->id = id;
|
||||
team->color[0] = 1.;
|
||||
team->color[1] = 1.;
|
||||
team->color[2] = 1.;
|
||||
team->color[3] = 1.f;
|
||||
|
||||
team->x = 0.;
|
||||
team->y = 0.;
|
||||
team->z = 0.;
|
||||
|
||||
team->points = 0;
|
||||
team->wins = 0;
|
||||
}
|
||||
|
||||
void game_reset_player(player_t *player) {
|
||||
player->id = 0;
|
||||
player->status = 0;
|
||||
player->team = NULL;
|
||||
player->x = 0.0;
|
||||
player->y = 0.0;
|
||||
player->z = 0.0;
|
||||
player->vx = 0.0;
|
||||
player->vy = 0.0;
|
||||
player->vz = 0.0;
|
||||
}
|
||||
|
||||
void game_reset_point(point_t *point) {
|
||||
point->status = 0;
|
||||
point->x = 0.0;
|
||||
point->y = 0.0;
|
||||
point->z = 0.0;
|
||||
}
|
||||
|
||||
void game_setup(game_t *game, int master, void(*explosion_callback)(double x,
|
||||
double y, double z)) {
|
||||
size_t i;
|
||||
if (master) {
|
||||
for (i = 0; i < GAME_TEAM_COUNT; i++)
|
||||
game_setup_team(&game->team[i], i);
|
||||
|
||||
for (i = 0; i < GAME_PLAYER_COUNT; i++)
|
||||
game_setup_player(&game->player[i]);
|
||||
|
||||
for (i = 0; i < GAME_POINT_COUNT; i++)
|
||||
game_setup_point(&game->point[i]);
|
||||
} else {
|
||||
for (i = 0; i < GAME_TEAM_COUNT; i++)
|
||||
game_reset_team(&game->team[i], i);
|
||||
|
||||
for (i = 0; i < GAME_PLAYER_COUNT; i++)
|
||||
game_reset_player(&game->player[i]);
|
||||
|
||||
for (i = 0; i < GAME_POINT_COUNT; i++)
|
||||
game_reset_point(&game->point[i]);
|
||||
}
|
||||
|
||||
game->explosion_callback = explosion_callback;
|
||||
game->max_player_id = 0;
|
||||
game->master = master;
|
||||
game->updateTime = 0.0;
|
||||
}
|
||||
|
||||
player_t *_game_free_player(game_t *game) {
|
||||
@ -87,12 +156,18 @@ void game_update_players(game_t *game, double dt) {
|
||||
player->x += player->vx * dt;
|
||||
player->y += player->vy * dt;
|
||||
player->z += player->vz * dt;
|
||||
|
||||
double distance2 = pow(player->x - player->team->x, 2) + pow(player->y
|
||||
- player->team->y, 2) + pow(player->z - player->team->z, 2);
|
||||
if (distance2 < 10000) {
|
||||
player->team->points += player->points;
|
||||
player->points = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _explode_bomb(game_t *game, bomb_t *bomb, void(*explosion_callback)(
|
||||
double x, double y, double z)) {
|
||||
size_t i;
|
||||
void _explode_bomb(game_t *game, bomb_t *bomb) {
|
||||
size_t i, j;
|
||||
for (i = 0; i < GAME_PLAYER_COUNT; i++) {
|
||||
player_t *player = &game->player[i];
|
||||
if (player->status == 0)
|
||||
@ -100,19 +175,25 @@ void _explode_bomb(game_t *game, bomb_t *bomb, void(*explosion_callback)(
|
||||
double distance2 = pow(player->x - bomb->x, 2) + pow(player->y
|
||||
- bomb->y, 2) + pow(player->z - bomb->z, 2);
|
||||
if (distance2 < 10000.0) {
|
||||
explosion_callback(player->x, player->y, player->z);
|
||||
game->explosion_callback(player->x, player->y, player->z);
|
||||
player->x = player->team->x + 100;
|
||||
player->y = player->team->y;
|
||||
player->z = player->team->z;
|
||||
player->vx = 0.;
|
||||
player->vy = 0.;
|
||||
player->vz = 0.;
|
||||
for (j = 0; j < player->points; j++) {
|
||||
point_t *point = game_spawn_point(game);
|
||||
point->x = player->x + 20.0 * rand2();
|
||||
point->y = player->x + 20.0 * rand2();
|
||||
point->z = player->x + 20.0 * rand2();
|
||||
}
|
||||
player->points = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void game_update_bombs(game_t *game, double dt, void(*explosion_callback)(
|
||||
double x, double y, double z)) {
|
||||
void game_update_bombs(game_t *game, double dt) {
|
||||
size_t i;
|
||||
for (i = 0; i < GAME_BOMB_COUNT; i++) {
|
||||
bomb_t *bomb = &game->bomb[i];
|
||||
@ -124,16 +205,53 @@ void game_update_bombs(game_t *game, double dt, void(*explosion_callback)(
|
||||
bomb->ttl -= dt;
|
||||
if (bomb->ttl < 0) {
|
||||
if (bomb->status == 1) {
|
||||
explosion_callback(bomb->x, bomb->y, bomb->z);
|
||||
game->explosion_callback(bomb->x, bomb->y, bomb->z);
|
||||
bomb->status = 2;
|
||||
} else if (bomb->ttl < 0.8) {
|
||||
_explode_bomb(game, bomb, explosion_callback);
|
||||
_explode_bomb(game, bomb);
|
||||
bomb->status = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _update_point(game_t *game, point_t *point) {
|
||||
size_t i;
|
||||
for (i = 0; i < GAME_PLAYER_COUNT; i++) {
|
||||
player_t *player = &game->player[i];
|
||||
if (player->status == 0)
|
||||
continue;
|
||||
double distance2 = pow(player->x - point->x, 2) + pow(player->y
|
||||
- point->y, 2) + pow(player->z - point->z, 2);
|
||||
if (distance2 > 1000.0)
|
||||
continue;
|
||||
point->status = 0;
|
||||
player->points += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void game_update_points(game_t *game, double dt) {
|
||||
size_t i;
|
||||
for (i = 0; i < GAME_POINT_COUNT; i++) {
|
||||
point_t *point = &game->point[i];
|
||||
if (point->status == 0)
|
||||
continue;
|
||||
_update_point(game, point);
|
||||
}
|
||||
}
|
||||
|
||||
void game_update(game_t *game, double dt) {
|
||||
const double delta = 1. / 60.;
|
||||
game->updateTime += dt;
|
||||
while (game->updateTime > delta * 0.8) {
|
||||
game_update_players(game, delta);
|
||||
game_update_bombs(game, delta);
|
||||
game_update_points(game, delta);
|
||||
game->updateTime -= delta;
|
||||
}
|
||||
}
|
||||
|
||||
size_t game_active_team_players(game_t *game, team_t *team) {
|
||||
size_t i, count = 0;
|
||||
for (i = 0; i < GAME_PLAYER_COUNT; i++) {
|
||||
@ -188,3 +306,14 @@ bomb_t *game_spawn_bomb(game_t *game) {
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
point_t *game_spawn_point(game_t *game) {
|
||||
size_t i;
|
||||
for (i = 0; i < GAME_POINT_COUNT; i++) {
|
||||
if (game->point[i].status == 0) {
|
||||
game->point[i].status = 1;
|
||||
return &game->point[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
25
src/game.h
25
src/game.h
@ -9,7 +9,8 @@ typedef struct game_t game_t;
|
||||
|
||||
#define GAME_TEAM_COUNT 2
|
||||
#define GAME_PLAYER_COUNT 64
|
||||
#define GAME_BOMB_COUNT (GAME_PLAYER_COUNT * 4)
|
||||
#define GAME_BOMB_COUNT (GAME_PLAYER_COUNT * 5)
|
||||
#define GAME_POINT_COUNT 50
|
||||
|
||||
struct player_t {
|
||||
uint16_t id;
|
||||
@ -18,6 +19,7 @@ struct player_t {
|
||||
double rx, ry, rz, rw;
|
||||
double vx, vy, vz;
|
||||
team_t *team;
|
||||
uint16_t points;
|
||||
};
|
||||
|
||||
struct bomb_t {
|
||||
@ -27,20 +29,32 @@ struct bomb_t {
|
||||
double ttl;
|
||||
};
|
||||
|
||||
struct point_t {
|
||||
uint8_t status;
|
||||
double x, y, z;
|
||||
};
|
||||
|
||||
struct team_t {
|
||||
uint16_t id;
|
||||
double x, y, z;
|
||||
float color[4];
|
||||
uint16_t points;
|
||||
uint16_t wins;
|
||||
};
|
||||
|
||||
struct game_t {
|
||||
team_t team[GAME_TEAM_COUNT];
|
||||
player_t player[GAME_PLAYER_COUNT];
|
||||
bomb_t bomb[GAME_BOMB_COUNT];
|
||||
point_t point[GAME_POINT_COUNT];
|
||||
int16_t max_player_id;
|
||||
int master;
|
||||
double updateTime;
|
||||
void(*explosion_callback)(double x, double y, double z);
|
||||
};
|
||||
|
||||
extern void game_setup(game_t *game);
|
||||
extern void game_setup(game_t *game, int master, void(*explosion_callback)(double x,
|
||||
double y, double z));
|
||||
extern team_t *game_team_with_least_players(game_t *game);
|
||||
extern player_t *game_spawn_player(game_t *game, team_t *team);
|
||||
extern player_t *game_spawn_player_id(game_t *game, team_t *team, uint16_t id);
|
||||
@ -49,7 +63,10 @@ extern player_t *game_player(game_t *game, uint16_t id);
|
||||
extern bomb_t *game_bomb(game_t *game, uint16_t index);
|
||||
extern void game_update_players(game_t *game, double dt);
|
||||
extern bomb_t *game_spawn_bomb(game_t *game);
|
||||
extern void game_update_bombs(game_t *game, double dt,
|
||||
void(*explosion_callback)(double x, double y, double z));
|
||||
extern point_t *game_spawn_point(game_t *game);
|
||||
extern void game_update_bombs(game_t *game, double dt);
|
||||
extern void game_update_points(game_t *game, double dt);
|
||||
extern void game_update(game_t *game, double dt);
|
||||
|
||||
|
||||
#endif
|
||||
|
121
src/main.cpp
121
src/main.cpp
@ -3,6 +3,7 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <enet/enet.h>
|
||||
#include <GL/glfw.h>
|
||||
|
||||
@ -63,7 +64,7 @@ void setup_opengl() {
|
||||
glEnable( GL_LIGHTING);
|
||||
|
||||
// Enable vertical sync (on cards that support it)
|
||||
glfwSwapInterval(0);
|
||||
glfwSwapInterval(1);
|
||||
}
|
||||
|
||||
void draw_team(team_t *team) {
|
||||
@ -95,7 +96,18 @@ void draw_bomb(bomb_t *bomb) {
|
||||
glMatrixMode( GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glTranslated(bomb->x, bomb->y, bomb->z);
|
||||
gluSphere(quadratic, 3.f, 32, 32);
|
||||
gluSphere(quadratic, 3.f, 4, 4);
|
||||
glPopMatrix();
|
||||
}
|
||||
void draw_point(point_t *point) {
|
||||
if (point->status == 0)
|
||||
return;
|
||||
GLfloat red[] = { 0.0f, 0.0f, 1.0f, 1.0f };
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
|
||||
glMatrixMode( GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glTranslated(point->x, point->y, point->z);
|
||||
gluSphere(quadratic, 3.f, 12, 12);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
@ -163,6 +175,7 @@ void setup_network(const char *remote) {
|
||||
#define MESSAGE_PLAYER_ACCELERATE 4
|
||||
#define MESSAGE_BOMB_DROP 5
|
||||
#define MESSAGE_BOMB_UPDATE 6
|
||||
#define MESSAGE_POINT_UPDATE 6
|
||||
|
||||
typedef struct message_t {
|
||||
uint16_t msg_id;
|
||||
@ -213,6 +226,13 @@ typedef struct bomb_update_meesage_t {
|
||||
double ttl;
|
||||
} bomb_update_meesage_t;
|
||||
|
||||
typedef struct point_update_mesage_t {
|
||||
uint16_t msg_id;
|
||||
uint16_t point_index;
|
||||
uint8_t status;
|
||||
double x, y, z;
|
||||
} point_update_meesage_t;
|
||||
|
||||
void send_player_updates(game_t *game) {
|
||||
size_t i;
|
||||
for (i = 0; i < GAME_PLAYER_COUNT; i++) {
|
||||
@ -265,6 +285,15 @@ void dispatch_message(enet_uint8 *data, size_t length, game_t *game) {
|
||||
player->vz = um->vz;
|
||||
break;
|
||||
}
|
||||
case MESSAGE_POINT_UPDATE: {
|
||||
point_update_mesage_t *msg = (point_update_mesage_t *) data;
|
||||
point_t *p = &game->point[msg->point_index];
|
||||
p->status = msg->status;
|
||||
p->x = msg->x;
|
||||
p->y = msg->y;
|
||||
p->z = msg->z;
|
||||
break;
|
||||
}
|
||||
case MESSAGE_PLAYER_ACCELERATE: {
|
||||
player_accelerate_message_t *um = (player_accelerate_message_t *) data;
|
||||
player_t *player = game_player(game, um->player_id);
|
||||
@ -319,6 +348,21 @@ void service_network(game_t *game) {
|
||||
enet_peer_send(event.peer, 0, packet);
|
||||
}
|
||||
|
||||
for (i = 0; i < GAME_POINT_COUNT; i++) {
|
||||
if (game->point[i].status == 0)
|
||||
continue;
|
||||
point_update_mesage_t msg;
|
||||
msg.msg_id = MESSAGE_POINT_UPDATE;
|
||||
msg.point_index = i;
|
||||
msg.status = game->point[i].status;
|
||||
msg.x = game->point[i].x;
|
||||
msg.y = game->point[i].y;
|
||||
msg.z = game->point[i].z;
|
||||
ENetPacket * packet = enet_packet_create(&msg, sizeof(msg),
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
enet_peer_send(event.peer, 0, packet);
|
||||
}
|
||||
|
||||
team_t *team = game_team_with_least_players(game);
|
||||
player_t *player = game_spawn_player(game, team);
|
||||
printf("Spwan as %d.%d\n", team->id, player->id);
|
||||
@ -374,6 +418,8 @@ void service_network(game_t *game) {
|
||||
}
|
||||
|
||||
void accelerate(game_t *game, double x, double y, double z) {
|
||||
if (local_player == 0)
|
||||
return;
|
||||
player_accelerate_message_t msg;
|
||||
msg.msg_id = MESSAGE_PLAYER_ACCELERATE;
|
||||
msg.player_id = local_player->id;
|
||||
@ -389,15 +435,15 @@ void accelerate(game_t *game, double x, double y, double z) {
|
||||
}
|
||||
}
|
||||
|
||||
void drop_bomb(game_t *game, double x, double y, double z, double ttl) {
|
||||
void drop_bomb(game_t *game, double rx, double ry, double rz, double ttl) {
|
||||
bomb_drop_meesage_t msg;
|
||||
msg.msg_id = MESSAGE_BOMB_DROP;
|
||||
msg.x = x;
|
||||
msg.y = y;
|
||||
msg.z = z;
|
||||
msg.vx = local_player->vx;
|
||||
msg.vy = local_player->vy;
|
||||
msg.vz = local_player->vz;
|
||||
msg.x = local_player->x + rx * 20;
|
||||
msg.y = local_player->y + ry * 20;
|
||||
msg.z = local_player->z + rz * 20;
|
||||
msg.vx = local_player->vx + rx * 100;
|
||||
msg.vy = local_player->vy + ry * 100;
|
||||
msg.vz = local_player->vz + rz * 100;
|
||||
msg.ttl = ttl;
|
||||
if (client_peer) {
|
||||
ENetPacket * packet = enet_packet_create(&msg, sizeof(msg),
|
||||
@ -499,6 +545,7 @@ void Application::loadConsoleFont() {
|
||||
glfwLoadTexture2D("data/fonts/console.tga", 0);
|
||||
oglf_load(&font, "data/fonts/console.fnt", font_id);
|
||||
}
|
||||
|
||||
void Application::prepareFrame(double rx, double ry, double rz) {
|
||||
// Get window size (may be different than the requested size)
|
||||
glfwGetWindowSize(&width, &height);
|
||||
@ -532,26 +579,29 @@ void Application::initialize(int argc, char ** argv) {
|
||||
gluQuadricNormals(quadratic, GLU_SMOOTH);
|
||||
gluQuadricTexture(quadratic, GL_TRUE);
|
||||
|
||||
game_setup(&game);
|
||||
|
||||
setup_opengl();
|
||||
|
||||
setup_explosion();
|
||||
|
||||
if (argc > 1) {
|
||||
server = 0;
|
||||
setup_network(argv[1]);
|
||||
} else {
|
||||
server = 1;
|
||||
}
|
||||
|
||||
game_setup(&game, server, explosion_callback);
|
||||
setup_opengl();
|
||||
setup_explosion();
|
||||
|
||||
if (server) {
|
||||
setup_network(NULL);
|
||||
team_t *team = game_team(&game, 0);
|
||||
local_player = game_spawn_player(&game, team);
|
||||
} else {
|
||||
setup_network(argv[1]);
|
||||
}
|
||||
|
||||
size_t i;
|
||||
running = GL_TRUE;
|
||||
last_time = glfwGetTime();
|
||||
last_player_update = last_time;
|
||||
last_bomb = last_time;
|
||||
last_bomb = last_time - 5.;
|
||||
glfwGetMousePos(&last_x, &last_y);
|
||||
|
||||
accelerate_schudule.setExact(true);
|
||||
@ -615,10 +665,9 @@ void Application::update() {
|
||||
}
|
||||
}
|
||||
if (glfwGetKey(GLFW_KEY_LCTRL)) {
|
||||
if (time - last_bomb > 5.0) {
|
||||
if (time - last_bomb > 1.0) {
|
||||
last_bomb = time;
|
||||
drop_bomb(&game, local_player->x + rx * 20.0, local_player->y + ry
|
||||
* 20.0, local_player->z + rz * 20.0, 5.0);
|
||||
drop_bomb(&game, rx, ry, rz, 5.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -627,15 +676,6 @@ void Application::update() {
|
||||
glEnable( GL_LIGHT0);
|
||||
glEnable( GL_LIGHTING);
|
||||
glEnable( GL_CULL_FACE);
|
||||
const float plane_color[] = { 0.2f, 0.3f, 0.4f, 1.0f };
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, plane_color);
|
||||
// Draw a textured quad
|
||||
glBegin( GL_QUADS);
|
||||
glVertex3f(-5000.0f, 5000.0f, -5000.0f);
|
||||
glVertex3f(5000.0f, 5000.0f, -5000.0f);
|
||||
glVertex3f(5000.0f, 5000.0f, 5000.0f);
|
||||
glVertex3f(-5000.0f, 5000.0f, 5000.0f);
|
||||
glEnd();
|
||||
for (size_t i = 0; i < GAME_TEAM_COUNT; i++)
|
||||
draw_team(&game.team[i]);
|
||||
|
||||
@ -645,6 +685,9 @@ void Application::update() {
|
||||
for (size_t i = 0; i < GAME_BOMB_COUNT; i++)
|
||||
draw_bomb(&game.bomb[i]);
|
||||
|
||||
for (size_t i = 0; i < GAME_POINT_COUNT; i++)
|
||||
draw_point(&game.point[i]);
|
||||
|
||||
glDisable(GL_LIGHT0);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_CULL_FACE);
|
||||
@ -652,7 +695,22 @@ void Application::update() {
|
||||
explosion.render();
|
||||
|
||||
oglf_begin(&font, width, height);
|
||||
oglf_print(&font, 40, 40, "Hello");
|
||||
if (local_player) {
|
||||
std::stringstream sstr;
|
||||
sstr << "Points: " << local_player->points;
|
||||
oglf_print(&font, 10, 10, sstr.str().c_str());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < GAME_TEAM_COUNT; i++) {
|
||||
std::stringstream sstr;
|
||||
if (local_player && &game.team[i] == local_player->team) {
|
||||
sstr << "Team " << i << " (yours) : " << game.team[i].points;
|
||||
} else {
|
||||
sstr << "Team " << i << " (other) : " << game.team[i].points;
|
||||
}
|
||||
oglf_print(&font, 10, (i + 2) * 15, sstr.str().c_str());
|
||||
}
|
||||
|
||||
oglf_end();
|
||||
|
||||
// Swap buffers
|
||||
@ -665,8 +723,7 @@ void Application::update() {
|
||||
send_player_updates(&game);
|
||||
}
|
||||
|
||||
game_update_players(&game, dt);
|
||||
game_update_bombs(&game, dt, explosion_callback);
|
||||
game_update(&game, dt);
|
||||
|
||||
last_time = time;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user