From 6fc4e795d27b49b3bb1a06ef8429b1cdafa7dcd6 Mon Sep 17 00:00:00 2001 From: gmueller Date: Sun, 9 Jan 2011 21:56:48 +0100 Subject: [PATCH] added points, sync still missing --- src/game.cpp | 155 ++++++++++++++++++++++++++++++++++++++++++++++----- src/game.h | 25 +++++++-- src/main.cpp | 121 +++++++++++++++++++++++++++++----------- 3 files changed, 252 insertions(+), 49 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 9be8982..7b24a79 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2,6 +2,14 @@ #include #include +#include + +#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) { +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_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_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; +} diff --git a/src/game.h b/src/game.h index e2460b0..97b25fa 100644 --- a/src/game.h +++ b/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 diff --git a/src/main.cpp b/src/main.cpp index 25f732f..cc6b335 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -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;