added points, sync still missing

This commit is contained in:
gmueller 2011-01-09 21:56:48 +01:00
parent 5112241a93
commit 6fc4e795d2
3 changed files with 252 additions and 49 deletions

View File

@ -2,6 +2,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.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) { void game_setup_team(team_t *team, uint8_t id) {
team->id = 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->x = 2000.0 * (id & (1 << 0));
team->y = 2000.0 * (id & (1 << 1)); team->y = 2000.0 * (id & (1 << 1));
team->z = 2000.0 * (id & (1 << 2)); team->z = 2000.0 * (id & (1 << 2));
team->points = 0;
team->wins = 0;
} }
void game_setup_player(player_t *player) { void game_setup_player(player_t *player) {
@ -21,16 +32,74 @@ void game_setup_player(player_t *player) {
player->team = NULL; player->team = NULL;
} }
void game_setup(game_t *game) { void game_setup_point(point_t *point) {
size_t i; 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++) for (i = 0; i < GAME_TEAM_COUNT; i++)
game_setup_team(&game->team[i], i); game_setup_team(&game->team[i], i);
for (i = 0; i < GAME_PLAYER_COUNT; i++) for (i = 0; i < GAME_PLAYER_COUNT; i++)
game_setup_player(&game->player[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->max_player_id = 0;
game->master = master;
game->updateTime = 0.0;
} }
player_t *_game_free_player(game_t *game) { 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->x += player->vx * dt;
player->y += player->vy * dt; player->y += player->vy * dt;
player->z += player->vz * 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)( void _explode_bomb(game_t *game, bomb_t *bomb) {
double x, double y, double z)) { size_t i, j;
size_t i;
for (i = 0; i < GAME_PLAYER_COUNT; i++) { for (i = 0; i < GAME_PLAYER_COUNT; i++) {
player_t *player = &game->player[i]; player_t *player = &game->player[i];
if (player->status == 0) 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 double distance2 = pow(player->x - bomb->x, 2) + pow(player->y
- bomb->y, 2) + pow(player->z - bomb->z, 2); - bomb->y, 2) + pow(player->z - bomb->z, 2);
if (distance2 < 10000.0) { 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->x = player->team->x + 100;
player->y = player->team->y; player->y = player->team->y;
player->z = player->team->z; player->z = player->team->z;
player->vx = 0.; player->vx = 0.;
player->vy = 0.; player->vy = 0.;
player->vz = 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)( void game_update_bombs(game_t *game, double dt) {
double x, double y, double z)) {
size_t i; size_t i;
for (i = 0; i < GAME_BOMB_COUNT; i++) { for (i = 0; i < GAME_BOMB_COUNT; i++) {
bomb_t *bomb = &game->bomb[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; bomb->ttl -= dt;
if (bomb->ttl < 0) { if (bomb->ttl < 0) {
if (bomb->status == 1) { if (bomb->status == 1) {
explosion_callback(bomb->x, bomb->y, bomb->z); game->explosion_callback(bomb->x, bomb->y, bomb->z);
bomb->status = 2; bomb->status = 2;
} else if (bomb->ttl < 0.8) { } else if (bomb->ttl < 0.8) {
_explode_bomb(game, bomb, explosion_callback); _explode_bomb(game, bomb);
bomb->status = 0; 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 game_active_team_players(game_t *game, team_t *team) {
size_t i, count = 0; size_t i, count = 0;
for (i = 0; i < GAME_PLAYER_COUNT; i++) { for (i = 0; i < GAME_PLAYER_COUNT; i++) {
@ -188,3 +306,14 @@ bomb_t *game_spawn_bomb(game_t *game) {
} }
return NULL; 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;
}

View File

@ -9,7 +9,8 @@ typedef struct game_t game_t;
#define GAME_TEAM_COUNT 2 #define GAME_TEAM_COUNT 2
#define GAME_PLAYER_COUNT 64 #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 { struct player_t {
uint16_t id; uint16_t id;
@ -18,6 +19,7 @@ struct player_t {
double rx, ry, rz, rw; double rx, ry, rz, rw;
double vx, vy, vz; double vx, vy, vz;
team_t *team; team_t *team;
uint16_t points;
}; };
struct bomb_t { struct bomb_t {
@ -27,20 +29,32 @@ struct bomb_t {
double ttl; double ttl;
}; };
struct point_t {
uint8_t status;
double x, y, z;
};
struct team_t { struct team_t {
uint16_t id; uint16_t id;
double x, y, z; double x, y, z;
float color[4]; float color[4];
uint16_t points;
uint16_t wins;
}; };
struct game_t { struct game_t {
team_t team[GAME_TEAM_COUNT]; team_t team[GAME_TEAM_COUNT];
player_t player[GAME_PLAYER_COUNT]; player_t player[GAME_PLAYER_COUNT];
bomb_t bomb[GAME_BOMB_COUNT]; bomb_t bomb[GAME_BOMB_COUNT];
point_t point[GAME_POINT_COUNT];
int16_t max_player_id; 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 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(game_t *game, team_t *team);
extern player_t *game_spawn_player_id(game_t *game, team_t *team, uint16_t id); 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 bomb_t *game_bomb(game_t *game, uint16_t index);
extern void game_update_players(game_t *game, double dt); extern void game_update_players(game_t *game, double dt);
extern bomb_t *game_spawn_bomb(game_t *game); extern bomb_t *game_spawn_bomb(game_t *game);
extern void game_update_bombs(game_t *game, double dt, extern point_t *game_spawn_point(game_t *game);
void(*explosion_callback)(double x, double y, double z)); 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 #endif

View File

@ -3,6 +3,7 @@
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <sstream>
#include <enet/enet.h> #include <enet/enet.h>
#include <GL/glfw.h> #include <GL/glfw.h>
@ -63,7 +64,7 @@ void setup_opengl() {
glEnable( GL_LIGHTING); glEnable( GL_LIGHTING);
// Enable vertical sync (on cards that support it) // Enable vertical sync (on cards that support it)
glfwSwapInterval(0); glfwSwapInterval(1);
} }
void draw_team(team_t *team) { void draw_team(team_t *team) {
@ -95,7 +96,18 @@ void draw_bomb(bomb_t *bomb) {
glMatrixMode( GL_MODELVIEW); glMatrixMode( GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glTranslated(bomb->x, bomb->y, bomb->z); 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(); glPopMatrix();
} }
@ -163,6 +175,7 @@ void setup_network(const char *remote) {
#define MESSAGE_PLAYER_ACCELERATE 4 #define MESSAGE_PLAYER_ACCELERATE 4
#define MESSAGE_BOMB_DROP 5 #define MESSAGE_BOMB_DROP 5
#define MESSAGE_BOMB_UPDATE 6 #define MESSAGE_BOMB_UPDATE 6
#define MESSAGE_POINT_UPDATE 6
typedef struct message_t { typedef struct message_t {
uint16_t msg_id; uint16_t msg_id;
@ -213,6 +226,13 @@ typedef struct bomb_update_meesage_t {
double ttl; double ttl;
} bomb_update_meesage_t; } 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) { void send_player_updates(game_t *game) {
size_t i; size_t i;
for (i = 0; i < GAME_PLAYER_COUNT; 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; player->vz = um->vz;
break; 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: { case MESSAGE_PLAYER_ACCELERATE: {
player_accelerate_message_t *um = (player_accelerate_message_t *) data; player_accelerate_message_t *um = (player_accelerate_message_t *) data;
player_t *player = game_player(game, um->player_id); 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); 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); team_t *team = game_team_with_least_players(game);
player_t *player = game_spawn_player(game, team); player_t *player = game_spawn_player(game, team);
printf("Spwan as %d.%d\n", team->id, player->id); 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) { void accelerate(game_t *game, double x, double y, double z) {
if (local_player == 0)
return;
player_accelerate_message_t msg; player_accelerate_message_t msg;
msg.msg_id = MESSAGE_PLAYER_ACCELERATE; msg.msg_id = MESSAGE_PLAYER_ACCELERATE;
msg.player_id = local_player->id; 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; bomb_drop_meesage_t msg;
msg.msg_id = MESSAGE_BOMB_DROP; msg.msg_id = MESSAGE_BOMB_DROP;
msg.x = x; msg.x = local_player->x + rx * 20;
msg.y = y; msg.y = local_player->y + ry * 20;
msg.z = z; msg.z = local_player->z + rz * 20;
msg.vx = local_player->vx; msg.vx = local_player->vx + rx * 100;
msg.vy = local_player->vy; msg.vy = local_player->vy + ry * 100;
msg.vz = local_player->vz; msg.vz = local_player->vz + rz * 100;
msg.ttl = ttl; msg.ttl = ttl;
if (client_peer) { if (client_peer) {
ENetPacket * packet = enet_packet_create(&msg, sizeof(msg), ENetPacket * packet = enet_packet_create(&msg, sizeof(msg),
@ -499,6 +545,7 @@ void Application::loadConsoleFont() {
glfwLoadTexture2D("data/fonts/console.tga", 0); glfwLoadTexture2D("data/fonts/console.tga", 0);
oglf_load(&font, "data/fonts/console.fnt", font_id); oglf_load(&font, "data/fonts/console.fnt", font_id);
} }
void Application::prepareFrame(double rx, double ry, double rz) { void Application::prepareFrame(double rx, double ry, double rz) {
// Get window size (may be different than the requested size) // Get window size (may be different than the requested size)
glfwGetWindowSize(&width, &height); glfwGetWindowSize(&width, &height);
@ -532,26 +579,29 @@ void Application::initialize(int argc, char ** argv) {
gluQuadricNormals(quadratic, GLU_SMOOTH); gluQuadricNormals(quadratic, GLU_SMOOTH);
gluQuadricTexture(quadratic, GL_TRUE); gluQuadricTexture(quadratic, GL_TRUE);
game_setup(&game);
setup_opengl();
setup_explosion();
if (argc > 1) { if (argc > 1) {
server = 0; server = 0;
setup_network(argv[1]);
} else { } else {
server = 1; server = 1;
}
game_setup(&game, server, explosion_callback);
setup_opengl();
setup_explosion();
if (server) {
setup_network(NULL); setup_network(NULL);
team_t *team = game_team(&game, 0); team_t *team = game_team(&game, 0);
local_player = game_spawn_player(&game, team); local_player = game_spawn_player(&game, team);
} else {
setup_network(argv[1]);
} }
size_t i; size_t i;
running = GL_TRUE; running = GL_TRUE;
last_time = glfwGetTime(); last_time = glfwGetTime();
last_player_update = last_time; last_player_update = last_time;
last_bomb = last_time; last_bomb = last_time - 5.;
glfwGetMousePos(&last_x, &last_y); glfwGetMousePos(&last_x, &last_y);
accelerate_schudule.setExact(true); accelerate_schudule.setExact(true);
@ -615,10 +665,9 @@ void Application::update() {
} }
} }
if (glfwGetKey(GLFW_KEY_LCTRL)) { if (glfwGetKey(GLFW_KEY_LCTRL)) {
if (time - last_bomb > 5.0) { if (time - last_bomb > 1.0) {
last_bomb = time; last_bomb = time;
drop_bomb(&game, local_player->x + rx * 20.0, local_player->y + ry drop_bomb(&game, rx, ry, rz, 5.0);
* 20.0, local_player->z + rz * 20.0, 5.0);
} }
} }
@ -627,15 +676,6 @@ void Application::update() {
glEnable( GL_LIGHT0); glEnable( GL_LIGHT0);
glEnable( GL_LIGHTING); glEnable( GL_LIGHTING);
glEnable( GL_CULL_FACE); 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++) for (size_t i = 0; i < GAME_TEAM_COUNT; i++)
draw_team(&game.team[i]); draw_team(&game.team[i]);
@ -645,6 +685,9 @@ void Application::update() {
for (size_t i = 0; i < GAME_BOMB_COUNT; i++) for (size_t i = 0; i < GAME_BOMB_COUNT; i++)
draw_bomb(&game.bomb[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_LIGHT0);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
@ -652,7 +695,22 @@ void Application::update() {
explosion.render(); explosion.render();
oglf_begin(&font, width, height); 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(); oglf_end();
// Swap buffers // Swap buffers
@ -665,8 +723,7 @@ void Application::update() {
send_player_updates(&game); send_player_updates(&game);
} }
game_update_players(&game, dt); game_update(&game, dt);
game_update_bombs(&game, dt, explosion_callback);
last_time = time; last_time = time;