From f8798d7c0cc82daf68a59694e0b1819b496517c5 Mon Sep 17 00:00:00 2001 From: /jedi/ Date: Tue, 27 Sep 2016 20:50:32 +0200 Subject: [PATCH 01/13] server files --- game/options.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/game/options.hpp b/game/options.hpp index 779e32e..5cd04a6 100644 --- a/game/options.hpp +++ b/game/options.hpp @@ -1,3 +1,4 @@ +#pragma once #define TEST_FLAG1 0 #define SHOW_FPS 1 From fe6779da7e24139888c504c45eb4cd254024e9b1 Mon Sep 17 00:00:00 2001 From: /jedi/ Date: Tue, 27 Sep 2016 20:51:03 +0200 Subject: [PATCH 02/13] server files --- game/server.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ game/server.hpp | 21 ++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 game/server.cpp create mode 100644 game/server.hpp diff --git a/game/server.cpp b/game/server.cpp new file mode 100644 index 0000000..f2cdd77 --- /dev/null +++ b/game/server.cpp @@ -0,0 +1,67 @@ +#include "server.hpp" + +#include "state/commands.hpp" + +#include "util.hpp" + +#include + +Game::Game() +{ + // advance simulation with 100 Hz + m_time_step = 1.0 / 100.0; + m_time_for_next_step = 0.0; + + m_state = new game::State(); + m_state->init(); + + m_state->addPlayer(0); + m_state->addPlayer(1); + m_state->addPlayer(2); + m_state->addPlayer(3); + //m_state->addPlayer(2); +} + +bool Game::cycle(float dt) +{ + static float acc = 0.0; + acc += dt; + + float spawnInterval = 0.1; + while(acc > spawnInterval) { + acc -= spawnInterval; + + float a = 2.0 * M_PI * util::randf_0_1(); + float speed = 0.002; + m_state->players[0]->addCommand(new game::ShootCommand(a, speed)); + } + +#if 1 + if (dt >= 10.0) { + //std::cout<<"time to big: " << dt << std::endl; + dt = m_time_step; + } + + //std::cout<<"adding dt: " << dt << std::endl; + m_time_for_next_step += dt; + + int steps = 0; + while(m_time_for_next_step >= m_time_step) { + //std::cout<<"time now: " << m_time_for_next_step << std::endl; + m_time_for_next_step -= m_time_step; + + m_state->advance(m_time_step); + steps++; + } + + //std::cout << m_time_for_next_step << " s remaining time, " << steps << " steps taken." << std::endl; + + return true; +#else + (void) dt; + + m_state->advance(dt); + + return true; +#endif +} diff --git a/game/server.hpp b/game/server.hpp new file mode 100644 index 0000000..bc02597 --- /dev/null +++ b/game/server.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "state/state.hpp" + +class Server { +public: + Server(); + + // main method of the game. run this regulary + // return false if want to exit. + // bool cycle(float dt); + + // for rendering +// const game::State *state() const { return m_state; } + +private: + game::State *m_state; + + float m_time_for_next_step; + float m_time_step; +}; From 67f43de22c50635117763b109618a0dac0e71c2d Mon Sep 17 00:00:00 2001 From: Andreas Ortmann Date: Tue, 27 Sep 2016 22:35:16 +0200 Subject: [PATCH 03/13] added a few more commands. --- game/game.cpp | 17 ++-------- game/state/commands.cpp | 40 ++++++++++++++++++++--- game/state/commands.hpp | 71 ++++++++++++++++++++++++++++++++++++++--- game/state/player.hpp | 5 ++- game/state/state.cpp | 16 +++++++++- game/state/state.hpp | 13 ++++++++ game/state/trace.cpp | 5 +++ game/state/trace.hpp | 4 +++ 8 files changed, 147 insertions(+), 24 deletions(-) diff --git a/game/game.cpp b/game/game.cpp index 38fcc0c..a6b96d9 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -9,7 +9,7 @@ Game::Game() { // advance simulation with 100 Hz - m_time_step = 1.0 / 100.0; + m_time_step = 1.0 / 100.0; m_time_for_next_step = 0.0; m_state = new game::State(); @@ -33,13 +33,9 @@ bool Game::cycle(float dt) float a = 2.0 * M_PI * util::randf_0_1(); float speed = 0.005; - m_state->players[0]->addCommand(new game::ShootCommand(a, speed)); - } -#if 1 - if (dt >= 10.0) { - //std::cout<<"time to big: " << dt << std::endl; - dt = m_time_step; + m_state->players[0]->addCommand(new game::SetSpeedCommand(speed)); + m_state->players[0]->addCommand(new game::ShootCommand(a)); } //std::cout<<"adding dt: " << dt << std::endl; @@ -57,11 +53,4 @@ bool Game::cycle(float dt) //std::cout << m_time_for_next_step << " s remaining time, " << steps << " steps taken." << std::endl; return true; -#else - (void) dt; - - m_state->advance(dt); - - return true; -#endif } diff --git a/game/state/commands.cpp b/game/state/commands.cpp index b84a214..2b82f27 100644 --- a/game/state/commands.cpp +++ b/game/state/commands.cpp @@ -10,23 +10,55 @@ namespace game { // TODO: idea // shoot multiple rockets at once or from different positions after // level up / upgrade ... - Missile *missile = new Missile(player, player->ship->position, m_angle, m_speed); + Missile *missile = new Missile(player, player->ship->position, m_angle, player->speed); Trace *trace = new Trace(missile); missile->trace = trace; - player->energy -= m_speed; + player->energy -= player->speed; player->missiles.push_back(missile); state->addTrace(trace); } - bool ShootCommand::allowed(const Player *player, const State *state) const + bool ShootCommand::ready(const Player *player, const State *state) const { (void) state; // TODO - return player->alive && player->energy >= m_speed; + return player->alive && player->energy >= player->speed; //return player->alive; } + + void ChangeNameCommand::apply(Player *player, State *state) const + { + // discard if not unique + for (const Player *other : state->players) { + if (m_name == other->name) { + std::cout << "name '" << m_name << "' already given to player #" << other->id << std::endl; + return; + } + } + + player->name = m_name; + } + + void SetSpeedCommand::apply(Player *player, State *state) const + { + (void) state; + player->speed = m_speed; + } + + void ClearTracesCommand::apply(Player *player, State *state) const + { + size_t i = 0; + while(i < state->traces.size()) { + Trace *trace = state->traces[i]; + if (trace->missile == nullptr && trace->missile->player == player) { + state->deleteTrace(trace); + } else { + i++; + } + } + } } diff --git a/game/state/commands.hpp b/game/state/commands.hpp index 5c8ff97..4ed914f 100644 --- a/game/state/commands.hpp +++ b/game/state/commands.hpp @@ -9,6 +9,10 @@ #include namespace game { + /** + * Base class for commands. + * must derive from this. + */ class Command { public: Command() @@ -19,7 +23,11 @@ namespace game { { } - virtual bool allowed(const Player *player, const State *state) const + // check whether the command is ready to execute. + // if not, wait. + // note: stuff like for admin should be done in execute() to discard the + // command and not block the queue. + virtual bool ready(const Player *player, const State *state) const { (void) player; (void) state; @@ -38,19 +46,74 @@ namespace game { virtual std::string name() const { return ""; } }; + /**********************************************************************/ + /* Implemented commands */ + /**********************************************************************/ + + /* + * Shoot at angle and optional speed. + * TODO + */ class ShootCommand : public Command { public: - ShootCommand(float angle, float speed) : m_angle(angle), m_speed(speed) + ShootCommand(float angle) : m_angle(angle) { } std::string name() const { return ""; } - void apply( Player *player, State *state) const; - bool allowed(const Player *player, const State *state) const; + void apply( Player *player, State *state) const; + bool ready(const Player *player, const State *state) const; private: float m_angle; + }; + + /** + * Change the name of the player if it will be uniuqe. + */ + class ChangeNameCommand : public Command { + public: + ChangeNameCommand(const std::string &name) : m_name(name) + { + } + + std::string name() const { return ""; } + + void apply(Player *player, State *state) const; + + private: + std::string m_name; + }; + + /** + * clear all traces of this player that are done + */ + class ClearTracesCommand : public Command { + public: + ClearTracesCommand() + { + } + + std::string name() const { return ""; } + + void apply(Player *player, State *state) const; + }; + + /** + * Set default speed of next shots for this player. + */ + class SetSpeedCommand : public Command { + public: + SetSpeedCommand(float speed) : m_speed(speed) + { + } + + std::string name() const { return ""; } + + void apply(Player *player, State *state) const; + + private: float m_speed; }; } diff --git a/game/state/player.hpp b/game/state/player.hpp index 199a411..3a6aeb4 100644 --- a/game/state/player.hpp +++ b/game/state/player.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -15,12 +16,14 @@ namespace game { public: int id; bool alive; + float speed; float energy; float deadTimeCounter; Ship *ship; + std::string name; std::vector missiles; - Player(int id) : id(id), alive(true), energy(0.0), ship(nullptr) + Player(int id) : id(id), alive(true), speed(0.01), energy(0.0), ship(nullptr), name("") { } diff --git a/game/state/state.cpp b/game/state/state.cpp index d84364d..71572e6 100644 --- a/game/state/state.cpp +++ b/game/state/state.cpp @@ -108,7 +108,7 @@ namespace game { // try to execute as much queued commands as possible. while (player->hasCommandInQueue()) { Command *command = player->peekCommand(); - if (!command->allowed(player, this)) { + if (!command->ready(player, this)) { break; } @@ -290,6 +290,20 @@ namespace game { traces.push_back(trace); } + void State::deleteTrace(Trace *trace) + { + // TODO: if traces of running missile is deleted it is dangerous + + size_t i = 0; + while(i < traces.size()) { + if (traces[i] == trace) { + delete(trace); + traces.erase(traces.begin()+i); + break; + } + } + } + void State::addExplosionFromHit(const Missile::Event *evt) { if (evt->hit == Hit::Nothing || evt->hit == Hit::BorderOfUniverse) { diff --git a/game/state/state.hpp b/game/state/state.hpp index 3fa7781..42d0659 100644 --- a/game/state/state.hpp +++ b/game/state/state.hpp @@ -9,6 +9,18 @@ #include "missile.hpp" +// TODO: +// give points for equipment / better weapons / more energy when: +// - player discovers the universe +// +// - the shot which made a kill was much longer than the direkt line between +// player and his target +// +// - add wormholes +// - add blackholes +// - shoot through suns which add a fire mantle to the rocket to make it more +// thick and dangerous but it gets destroyed after some time. + namespace game { // forward declarations class Command; @@ -56,6 +68,7 @@ namespace game { // add a trace to the list of traces. void addTrace(Trace *trace); + void deleteTrace(Trace *trace); /*************************************************************************/ /* Rendering */ diff --git a/game/state/trace.cpp b/game/state/trace.cpp index 4d93d2c..392076e 100644 --- a/game/state/trace.cpp +++ b/game/state/trace.cpp @@ -24,4 +24,9 @@ namespace game { points.push_back(TracePoint(missile)); } } + + void Trace::finish() + { + missile = nullptr; + } } diff --git a/game/state/trace.hpp b/game/state/trace.hpp index ab33b2f..7af85dc 100644 --- a/game/state/trace.hpp +++ b/game/state/trace.hpp @@ -21,6 +21,10 @@ namespace game { // the missile) in case the fidelityCounter would skip the current position. void addPointFromMissile(bool forceAdd=false); + // call this to mark the trace as finish and disconnect it from the + // missile. + void finish(); + // TODO: add extendLastPointToPosition() method for saving points / // optimization later on From eaba518ce4ef0797419ed7c70128bebf4a5e392d Mon Sep 17 00:00:00 2001 From: Andreas Ortmann Date: Tue, 27 Sep 2016 23:07:11 +0200 Subject: [PATCH 04/13] fiexd cleartraces command. --- game/game.cpp | 19 +++++++++++++++++++ game/state/commands.cpp | 9 +++++++-- game/state/state.cpp | 38 +++++++++++++++++++++++++++++--------- game/state/state.hpp | 5 ++++- game/state/trace.cpp | 14 +++++++++++++- game/state/trace.hpp | 11 +++++++++-- 6 files changed, 81 insertions(+), 15 deletions(-) diff --git a/game/game.cpp b/game/game.cpp index a6b96d9..128cdca 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -24,8 +24,20 @@ Game::Game() bool Game::cycle(float dt) { + static float total = 0.0; static float acc = 0.0; + + //if (total == 0.0) { + // float speed = 0.005; + // m_state->players[0]->addCommand(new game::SetSpeedCommand(speed)); + // for (int i=0; i<100; i++) { + // float a = 2.0 * M_PI * util::randf_0_1(); + // m_state->players[0]->addCommand(new game::ShootCommand(a)); + // } + //} + acc += dt; + total += dt; float spawnInterval = 0.1; while(acc > spawnInterval) { @@ -36,6 +48,13 @@ bool Game::cycle(float dt) m_state->players[0]->addCommand(new game::SetSpeedCommand(speed)); m_state->players[0]->addCommand(new game::ShootCommand(a)); + + //static bool done = false; + //if (total >= 10.0 && !done) { + // done = true; + + // m_state->players[0]->addCommand(new game::ClearTracesCommand()); + //} } //std::cout<<"adding dt: " << dt << std::endl; diff --git a/game/state/commands.cpp b/game/state/commands.cpp index 2b82f27..5dac8e0 100644 --- a/game/state/commands.cpp +++ b/game/state/commands.cpp @@ -2,6 +2,8 @@ #include "trace.hpp" +#include + namespace game { void ShootCommand::apply(Player *player, State *state) const { @@ -51,11 +53,14 @@ namespace game { void ClearTracesCommand::apply(Player *player, State *state) const { + std::cout<<"clearing traces!!!" << std::endl; + size_t i = 0; while(i < state->traces.size()) { Trace *trace = state->traces[i]; - if (trace->missile == nullptr && trace->missile->player == player) { - state->deleteTrace(trace); + if (trace->missile == nullptr && trace->player == player) { + state->deleteTrace(i); + } else { i++; } diff --git a/game/state/state.cpp b/game/state/state.cpp index 71572e6..e76e23e 100644 --- a/game/state/state.cpp +++ b/game/state/state.cpp @@ -145,12 +145,9 @@ namespace game { // TODO // add points - // + // TODO // message - // - // TODO - // respawn timer } void State::advancePlayerMissiles(float dt) @@ -166,7 +163,9 @@ namespace game { const bool isHit = (evt.hit != Hit::Nothing); - missile->trace->addPointFromMissile(isHit); // force point if missile gets destroyed a + if (missile->trace != nullptr) { + missile->trace->addPointFromMissile(isHit); // force point if missile gets destroyed a + } if (!isHit) { i++; @@ -192,6 +191,10 @@ namespace game { addExplosionFromHit(&evt); + if (missile->trace != nullptr) { + missile->trace->finish(); + } + player->missiles.erase(player->missiles.begin() + i); delete(missile); //std::cout<= traces.size()) { + std::cerr << "can't find trace with invalid index " << index << std::endl; + return; + } + + Trace *trace = traces[index]; + + //std::cout<<"removing a trace" << std::endl; + if (trace->missile != nullptr) { + // delete backlink. + // XXX: there's a missile without a trace now. + trace->missile->trace = nullptr; + } + + traces.erase(traces.begin() + index); + delete(trace); + } + void State::deleteTrace(Trace *trace) { - // TODO: if traces of running missile is deleted it is dangerous - size_t i = 0; while(i < traces.size()) { if (traces[i] == trace) { - delete(trace); - traces.erase(traces.begin()+i); + deleteTrace(i); break; } } diff --git a/game/state/state.hpp b/game/state/state.hpp index 42d0659..7128966 100644 --- a/game/state/state.hpp +++ b/game/state/state.hpp @@ -68,7 +68,10 @@ namespace game { // add a trace to the list of traces. void addTrace(Trace *trace); - void deleteTrace(Trace *trace); + + // delete traces with this command + void deleteTrace(Trace *trace); // using a pointer + void deleteTrace(size_t index); // using an index /*************************************************************************/ /* Rendering */ diff --git a/game/state/trace.cpp b/game/state/trace.cpp index 392076e..0b51695 100644 --- a/game/state/trace.cpp +++ b/game/state/trace.cpp @@ -4,6 +4,8 @@ #include "missile.hpp" +#include + namespace game { Trace::TracePoint::TracePoint(const Missile *missile) : position(missile->position) @@ -11,7 +13,16 @@ namespace game { { } - Trace::Trace(const Missile *missile) : missile(missile), fidelityCounter(0) + Trace::~Trace() + { + //std::cout<<"~Trace()" << std::endl; + } + + Trace::Trace(Missile *missile) + : missile(missile) + , player(missile->player) + , fidelityCounter(0) + , age(0.0) { points.push_back(TracePoint(missile)); } @@ -27,6 +38,7 @@ namespace game { void Trace::finish() { + //std::cout<<"trace finished now!" << std::endl; missile = nullptr; } } diff --git a/game/state/trace.hpp b/game/state/trace.hpp index 7af85dc..2b4f4f0 100644 --- a/game/state/trace.hpp +++ b/game/state/trace.hpp @@ -5,6 +5,7 @@ namespace game { class Missile; + class Player; /* * Trace of a missile through the space. @@ -12,7 +13,8 @@ namespace game { */ class Trace { public: - Trace(const Missile *missile); + Trace(Missile *missile); + ~Trace(); // Add the current position of the missile as a new point on the // trace. @@ -39,11 +41,16 @@ namespace game { }; std::vector points; - const Missile *missile; // missile which creates this path. + Missile *missile; // missile which creates this path. + Player *player; // counter which is incremented each time addPointFromMissile() is called. // when reaching a certain value the point is saved for // optimization. int fidelityCounter; + + // age of the trace. if too old, it can be removed to save + // space/power + float age; }; } From e1eb158f3f1e59856123dc2a5bbd5079bce0b756 Mon Sep 17 00:00:00 2001 From: Andreas Ortmann Date: Tue, 27 Sep 2016 23:16:25 +0200 Subject: [PATCH 05/13] small fix --- game/game.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/game/game.cpp b/game/game.cpp index 128cdca..b0b590b 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -8,7 +8,7 @@ Game::Game() { - // advance simulation with 100 Hz + // advance simulation in fixed steps with 100 Hz m_time_step = 1.0 / 100.0; m_time_for_next_step = 0.0; @@ -24,6 +24,9 @@ Game::Game() bool Game::cycle(float dt) { +#if 1 + // XXX the following is just testing code to do things + static float total = 0.0; static float acc = 0.0; @@ -36,18 +39,18 @@ bool Game::cycle(float dt) // } //} - acc += dt; + acc += dt; total += dt; float spawnInterval = 0.1; while(acc > spawnInterval) { acc -= spawnInterval; - float a = 2.0 * M_PI * util::randf_0_1(); + float angle = 2.0 * M_PI * util::randf_0_1(); float speed = 0.005; m_state->players[0]->addCommand(new game::SetSpeedCommand(speed)); - m_state->players[0]->addCommand(new game::ShootCommand(a)); + m_state->players[0]->addCommand(new game::ShootCommand(angle)); //static bool done = false; //if (total >= 10.0 && !done) { @@ -56,6 +59,7 @@ bool Game::cycle(float dt) // m_state->players[0]->addCommand(new game::ClearTracesCommand()); //} } +#endif //std::cout<<"adding dt: " << dt << std::endl; m_time_for_next_step += dt; From 1b3702db8af3055a18f0b85ac9f2985697a5d87d Mon Sep 17 00:00:00 2001 From: Andreas Ortmann Date: Tue, 27 Sep 2016 23:29:26 +0200 Subject: [PATCH 06/13] added sun --- game/state/planet.hpp | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/game/state/planet.hpp b/game/state/planet.hpp index 0407683..38f02b6 100644 --- a/game/state/planet.hpp +++ b/game/state/planet.hpp @@ -2,11 +2,38 @@ #include "object.hpp" +#include + namespace game { class Planet : public Object { public: - Planet(const glm::vec2 &pos, float r) : Object(pos, r) + /** + * Planets are build out of one material. + * TODO: support mixture or multiple material per planet. + */ + enum class Material { + Rock, + Metal, + Sand, + Gas, + Ice, + Water, + Sun + }; + + Planet(const glm::vec2 &pos, float r) : Planet(pos, r, Material::Rock) { } + + Planet(const glm::vec2 &pos, float r, Material mat) + : Object(pos, r) + , material(mat) + , seed(rand()) + { + } + + // nice for rendering attributes + Material material; + int seed; }; } From bfa7be68a99825b0badcd45edc2c7471fa25ee26 Mon Sep 17 00:00:00 2001 From: Andreas Ortmann Date: Tue, 27 Sep 2016 23:50:44 +0200 Subject: [PATCH 07/13] added not complete take over playeer command. --- game/state/commands.cpp | 14 ++++++++++++++ game/state/commands.hpp | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/game/state/commands.cpp b/game/state/commands.cpp index 5dac8e0..1a64d89 100644 --- a/game/state/commands.cpp +++ b/game/state/commands.cpp @@ -66,4 +66,18 @@ namespace game { } } } + +#if 0 + bool TakeOverPlayerCommand::ready(const Player *player, const State *state) const + { + (void) state; + return state->havePlayerGrantFor(player->id, m_otherPlayerId); + } + + void TakeOverPlayerCommand::apply(Player *player, State *state) const + { + if ( + state->playerGrant(player->id, m_otherPlayerId); + } +#endif } diff --git a/game/state/commands.hpp b/game/state/commands.hpp index 4ed914f..dd88c0c 100644 --- a/game/state/commands.hpp +++ b/game/state/commands.hpp @@ -116,4 +116,25 @@ namespace game { private: float m_speed; }; + +#if 0 + /** + * Take over a session for a player that left. + * An admin must confirm this command. + */ + class TakeOverPlayerCommand : public Command { + public: + TakeOverPlayerCommand(int otherPlayerId) : m_otherPlayerId(otherPlayerId) + { + } + + std::string name() const { return ""; } + + void apply( Player *player, State *state) const; + bool ready(const Player *player, const State *state) const; + + private: + int m_otherPlayerId; + }; +#endif } From 1e90a1c9c8f8ca3cf7e2e760d1b499f45ef2544a Mon Sep 17 00:00:00 2001 From: Andreas Ortmann Date: Wed, 28 Sep 2016 00:13:03 +0200 Subject: [PATCH 08/13] adding small stuff to limit traces --- game/state/missile.cpp | 2 +- game/state/missile.hpp | 12 +++++++++++- game/state/planet.hpp | 11 ++++++----- game/state/state.cpp | 13 ++++++++++++- game/state/state.hpp | 1 + 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/game/state/missile.cpp b/game/state/missile.cpp index 08a04b7..cbc3e58 100644 --- a/game/state/missile.cpp +++ b/game/state/missile.cpp @@ -49,7 +49,7 @@ namespace game { if (dist <= planet->radius) { // TODO: collect all hits and return the first one only // TODO: find exact hit position! - return Missile::Event(position, Hit::Planet); + return Missile::Event(position, planet->id); } dist *= 20.0; diff --git a/game/state/missile.hpp b/game/state/missile.hpp index 2763fe7..c7aa1df 100644 --- a/game/state/missile.hpp +++ b/game/state/missile.hpp @@ -22,7 +22,8 @@ namespace game { // stops existing afterwards. class Event { public: - Event(const glm::vec2 &pos) : Event(pos, Hit::Nothing) + Event(const glm::vec2 &pos) + : Event(pos, Hit::Nothing) { } @@ -31,6 +32,11 @@ namespace game { { } + Event(const glm::vec2 &pos, int planetId) : Event(pos, Hit::Planet) + { + this->planetId = planetId; + } + Event(const glm::vec2 &pos, int playerIdKiller, int playerIdVictim) : Event(pos, Hit::Ship) { @@ -41,8 +47,12 @@ namespace game { Hit hit; glm::vec2 position; + // if a player was hit, these are valid. int playerIdKiller; int playerIdVictim; + + // if a planet was hit, this is valid + int planetId; }; Missile(Player *player, const glm::vec2 &pos, float angle, float speed); diff --git a/game/state/planet.hpp b/game/state/planet.hpp index 38f02b6..e6ff6e7 100644 --- a/game/state/planet.hpp +++ b/game/state/planet.hpp @@ -21,19 +21,20 @@ namespace game { Sun }; - Planet(const glm::vec2 &pos, float r) : Planet(pos, r, Material::Rock) + Planet(const glm::vec2 &pos, int id, float r) : Planet(pos, id, r, Material::Rock) { } - Planet(const glm::vec2 &pos, float r, Material mat) + Planet(const glm::vec2 &pos, int id, float r, Material mat) : Object(pos, r) + , id(id) , material(mat) , seed(rand()) { } - // nice for rendering attributes - Material material; - int seed; + int id; + Material material; // for rendering and physics (can fly through sun and outer gas planets) + int seed; // just for rendering variation }; } diff --git a/game/state/state.cpp b/game/state/state.cpp index e76e23e..fd76907 100644 --- a/game/state/state.cpp +++ b/game/state/state.cpp @@ -25,6 +25,7 @@ namespace game { m_maxMissileDistance = 2.0; m_playerRespawnTime = 2.0; m_defaultEnergy = 10.0; + m_maxNumTraces = 10; bool planetsOnCircle = false; @@ -45,7 +46,7 @@ namespace game { } } while(glm::length(pos) < 0.2 && tries++ < 1000); - planets.push_back(new Planet(pos, 0.03 + 0.07*util::randf_0_1())); + planets.push_back(new Planet(pos, i, 0.03 + 0.07*util::randf_0_1())); } } @@ -290,6 +291,16 @@ namespace game { void State::addTrace(Trace *trace) { + //int count = 0; + //for (Trace *old : traces) { + // if (old->playerId == trace->playerId) { + // count++; + // } + //} + + //if (count > m_maxNumTraces) { + //} + traces.push_back(trace); } diff --git a/game/state/state.hpp b/game/state/state.hpp index 7128966..88718cb 100644 --- a/game/state/state.hpp +++ b/game/state/state.hpp @@ -111,5 +111,6 @@ namespace game { float m_playerRespawnTime; float m_shipRadius; float m_defaultEnergy; + int m_maxNumTraces; }; }; From 0e8e41e4fbbd1a3a12db171743ebd9893a480c03 Mon Sep 17 00:00:00 2001 From: /jedi/ Date: Wed, 28 Sep 2016 00:26:36 +0200 Subject: [PATCH 09/13] server open and event loop --- game/CMakeLists.txt | 3 +- game/main.cpp | 23 +++++++++++++--- game/opengl.cpp | 18 ++++-------- game/opengl.hpp | 37 ++++++++++++++----------- game/server.cpp | 67 --------------------------------------------- game/server.hpp | 44 ++++++++++++++++++++--------- game/session.hpp | 63 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 141 insertions(+), 114 deletions(-) delete mode 100644 game/server.cpp create mode 100644 game/session.hpp diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 8d2e44f..d3995c4 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -35,7 +35,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${OPENGL_INCLUDE_DIR}) include_directories(${CMAKE_SOURCE_DIR}/libs/glm/) +include_directories(${CMAKE_SOURCE_DIR}/libs/asio/asio/include/) add_executable(game ${GAME_SRC} ${GAME_HEADERS}) setup_target(game) -target_link_libraries(game X11 epoxy) +target_link_libraries(game X11 epoxy pthread) diff --git a/game/main.cpp b/game/main.cpp index bc79379..6be6ec0 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -1,17 +1,24 @@ -#include "opengl.hpp" - #include #include +#include +#include +#include "opengl.hpp" #include "game_window.hpp" +#include "server.hpp" #include "options.hpp" uint64_t optionsFlags; + +using asio::ip::tcp; + using namespace std; int main(int argc, char *argv[]) { + + char port[]="3490"; char c; static struct option long_options[] = @@ -56,8 +63,16 @@ int main(int argc, char *argv[]) { } } + asio::io_service io_service; + Server s(io_service, atoi(port) ); + GameWindow window(500, 500); window.set_maxfps(60.0); - window.loop(); - window.stop(); + + while(window.running()){ + window.poll(); + io_service.poll(); + } + + return 0; } diff --git a/game/opengl.cpp b/game/opengl.cpp index fde9da1..0ac19ad 100644 --- a/game/opengl.cpp +++ b/game/opengl.cpp @@ -101,18 +101,11 @@ void endofthejedi::GLWindow::handle(XEvent event) { void endofthejedi::GLWindow::swap() { glXSwapBuffers(m_display, m_window); } -void endofthejedi::GLWindow::loop() { - m_running = true; +void endofthejedi::GLWindow::poll() { - timespec prev; - timespec current; - clock_gettime(CLOCK_MONOTONIC_RAW, &prev); - clock_gettime(CLOCK_MONOTONIC_RAW, ¤t); + clock_gettime(CLOCK_MONOTONIC_RAW, &prev); + clock_gettime(CLOCK_MONOTONIC_RAW, ¤t); - double delta = 0.0; - double sleeptime = 0.0; - - while (m_running) { handleevents(); render(delta); swap(); @@ -132,11 +125,10 @@ void endofthejedi::GLWindow::loop() { m_fps = (1000000000.0/delta); //std::cout << m_fps << "\n"; } - } } void endofthejedi::GLWindow::stop() { m_running = false; } - -void endofthejedi::GLWindow::init() {} +bool endofthejedi::GLWindow::running() { return m_running; } +void endofthejedi::GLWindow::init() { m_running = true; } void endofthejedi::GLWindow::render(double time) { UNUSED(time) } void endofthejedi::GLWindow::resize() {} diff --git a/game/opengl.hpp b/game/opengl.hpp index 2114682..d6aed00 100644 --- a/game/opengl.hpp +++ b/game/opengl.hpp @@ -10,11 +10,11 @@ namespace endofthejedi { class GLWindow { - private: + private: //X-related stuff - Display* m_display; - Window m_rootwnd; - GLint m_attributes[23] = + Display* m_display; + Window m_rootwnd; + GLint m_attributes[23] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, @@ -29,17 +29,21 @@ class GLWindow { None }; - XVisualInfo* m_visualinfo; - Colormap m_colormap; - XSetWindowAttributes m_swa; - Window m_window; - GLXContext m_glcontext; - XWindowAttributes m_gwa; + XVisualInfo* m_visualinfo; + Colormap m_colormap; + XSetWindowAttributes m_swa; + Window m_window; + GLXContext m_glcontext; + XWindowAttributes m_gwa; Atom m_atomWmDeleteWindow; //End of X related stuff unsigned int m_width; unsigned int m_height; + double delta = 0.0; + double sleeptime = 0.0; + timespec prev; + timespec current; //mainloop condition bool m_running = false; @@ -48,9 +52,7 @@ class GLWindow { //if maxfps = 0 there's no fps limit double m_maxfps; - void handleevents(); - - protected: + protected: //ancestors shall override these methods virtual void init(); //called by mainloop periodically @@ -62,16 +64,19 @@ class GLWindow { //as it handles the close calls & resizing virtual void handle(XEvent event); + virtual void handleevents(); + public: //initializes the X Window & creates an OpenGL context - GLWindow(unsigned int width, unsigned int height); - ~GLWindow(); + GLWindow(unsigned int width, unsigned int height); + ~GLWindow(); //mainloop does event handling & calls render/swap - void loop(); + void poll(); void swap(); //stops the mainloop by setting m_running false void stop(); + bool running(); //getters unsigned int getheight() const { diff --git a/game/server.cpp b/game/server.cpp deleted file mode 100644 index f2cdd77..0000000 --- a/game/server.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "server.hpp" - -#include "state/commands.hpp" - -#include "util.hpp" - -#include - -Game::Game() -{ - // advance simulation with 100 Hz - m_time_step = 1.0 / 100.0; - m_time_for_next_step = 0.0; - - m_state = new game::State(); - m_state->init(); - - m_state->addPlayer(0); - m_state->addPlayer(1); - m_state->addPlayer(2); - m_state->addPlayer(3); - //m_state->addPlayer(2); -} - -bool Game::cycle(float dt) -{ - static float acc = 0.0; - acc += dt; - - float spawnInterval = 0.1; - while(acc > spawnInterval) { - acc -= spawnInterval; - - float a = 2.0 * M_PI * util::randf_0_1(); - float speed = 0.002; - m_state->players[0]->addCommand(new game::ShootCommand(a, speed)); - } - -#if 1 - if (dt >= 10.0) { - //std::cout<<"time to big: " << dt << std::endl; - dt = m_time_step; - } - - //std::cout<<"adding dt: " << dt << std::endl; - m_time_for_next_step += dt; - - int steps = 0; - while(m_time_for_next_step >= m_time_step) { - //std::cout<<"time now: " << m_time_for_next_step << std::endl; - m_time_for_next_step -= m_time_step; - - m_state->advance(m_time_step); - steps++; - } - - //std::cout << m_time_for_next_step << " s remaining time, " << steps << " steps taken." << std::endl; - - return true; -#else - (void) dt; - - m_state->advance(dt); - - return true; -#endif -} diff --git a/game/server.hpp b/game/server.hpp index bc02597..7b6e59a 100644 --- a/game/server.hpp +++ b/game/server.hpp @@ -1,21 +1,39 @@ #pragma once -#include "state/state.hpp" +//#include +//#include +//#include +#include -class Server { +#include "session.hpp" + +using asio::ip::tcp; + +class Server +{ public: - Server(); - - // main method of the game. run this regulary - // return false if want to exit. - // bool cycle(float dt); - - // for rendering -// const game::State *state() const { return m_state; } + Server(asio::io_service& io_service, short port) + : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)), + socket_(io_service) + { + do_accept(); + } private: - game::State *m_state; + void do_accept() + { + acceptor_.async_accept(socket_, + [this](std::error_code ec) + { + if (!ec) + { + std::make_shared(std::move(socket_))->start(); + } - float m_time_for_next_step; - float m_time_step; + do_accept(); + }); + } + + tcp::acceptor acceptor_; + tcp::socket socket_; }; diff --git a/game/session.hpp b/game/session.hpp new file mode 100644 index 0000000..0c1a04e --- /dev/null +++ b/game/session.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include +#include + +using asio::ip::tcp; + +class Session + : public std::enable_shared_from_this +{ +public: + Session(tcp::socket socket) + : socket_(std::move(socket)) + { + } + + void start() + { + auto self(shared_from_this()); + char hello[] = "\nUse \"n name\" to change name, \"v velocity\" to change velocity, \"c\" to clear past shots or \"q\" to close the connection.\nEverything else is interpreted as a shooting angle.\n\n>"; + asio::async_write(socket_, asio::buffer(hello, strlen(hello)), + [this, self](std::error_code ec, std::size_t /*length*/) + { + if (!ec) + { + do_read(); + } + }); + } + +private: + void do_read() + { + auto self(shared_from_this()); + socket_.async_read_some(asio::buffer(data_, max_length), + [this, self](std::error_code ec, std::size_t length) + { + if (!ec) + { + do_write(length); + } + }); + } + + void do_write(std::size_t length) + { + auto self(shared_from_this()); + asio::async_write(socket_, asio::buffer(data_, length), + [this, self](std::error_code ec, std::size_t /*length*/) + { + if (!ec) + { + do_read(); + } + }); + } + + tcp::socket socket_; + enum { max_length = 1024 }; + char data_[max_length]; +}; From ef38da703ecc270092f6c93445cbe3831ce77065 Mon Sep 17 00:00:00 2001 From: /jedi/ Date: Wed, 28 Sep 2016 01:48:34 +0200 Subject: [PATCH 10/13] networking addPlayer --- game/game.cpp | 6 +----- game/game.hpp | 2 +- game/game_window.hpp | 20 ++++++++++---------- game/main.cpp | 20 +++++++++++--------- game/server.hpp | 6 ++++-- game/session.hpp | 26 ++++++++++++++++++-------- game/state/state.cpp | 4 +++- game/state/state.hpp | 3 ++- 8 files changed, 50 insertions(+), 37 deletions(-) diff --git a/game/game.cpp b/game/game.cpp index 38fcc0c..2d07b9f 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -15,11 +15,7 @@ Game::Game() m_state = new game::State(); m_state->init(); - m_state->addPlayer(0); - m_state->addPlayer(1); - m_state->addPlayer(2); - m_state->addPlayer(3); - //m_state->addPlayer(2); + m_state->addPlayer(); } bool Game::cycle(float dt) diff --git a/game/game.hpp b/game/game.hpp index 9c9512a..36a1de6 100644 --- a/game/game.hpp +++ b/game/game.hpp @@ -11,7 +11,7 @@ public: bool cycle(float dt); // for rendering - const game::State *state() const { return m_state; } + game::State *state() const { return m_state; } private: game::State *m_state; diff --git a/game/game_window.hpp b/game/game_window.hpp index 8bd7c4f..02c1aa0 100644 --- a/game/game_window.hpp +++ b/game/game_window.hpp @@ -27,30 +27,30 @@ protected: //if (!once) { // once = true; // for (int i=0; i<1000; i++) { - // m_game.cycle(time); + // m_game->cycle(time); // } //} - if (!m_game.cycle(static_cast(time/1000000000.0))) { + if (!m_game->cycle(static_cast(time/1000000000.0))) { std::cout<<"stopping the game..." << std::endl; stop(); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - for (const game::Planet *planet : m_game.state()->planets) { + for (const game::Planet *planet : m_game->state()->planets) { drawPlanet(planet->position, planet->radius); } - for (const game::Trace *trace : m_game.state()->traces) { + for (const game::Trace *trace : m_game->state()->traces) { drawTrace(trace); } - for (const game::Ship *ship : m_game.state()->ships) { + for (const game::Ship *ship : m_game->state()->ships) { drawShip(ship->position); } - for (const game::Player *player : m_game.state()->players) { + for (const game::Player *player : m_game->state()->players) { for (const game::Missile *missile : player->missiles) { drawMissile(missile->position); } @@ -64,7 +64,7 @@ protected: //std::cout<<"draw ship @ " << pos.x << ", " << pos.y << std::endl; glm::vec3 color = glm::vec3(0.2, 1.0, 0.3); - float radius = m_game.state()->shipRadius(); + float radius = m_game->state()->shipRadius(); m_renderer.drawCircle(pos.x, pos.y, radius, color.x, color.y, color.z, 12); } @@ -93,11 +93,11 @@ protected: } public: - GameWindow(unsigned int width, unsigned int height) - : endofthejedi::GLWindow(width, height) {} + GameWindow(unsigned int width, unsigned int height, Game* game) + : endofthejedi::GLWindow(width, height) { m_game = game; } private: - Game m_game; + Game *m_game; endofthejedi::Renderer m_renderer; }; diff --git a/game/main.cpp b/game/main.cpp index 6be6ec0..f33a738 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -31,7 +31,7 @@ int main(int argc, char *argv[]) { // {"add", no_argument, 0, 'a'}, // {"append", no_argument, 0, 'b'}, // {"delete", required_argument, 0, 'd'}, -// {"create", required_argument, 0, 'c'}, + {"port", required_argument, 0, 'p'}, {"fps", no_argument, 0, 'f'}, {0, 0, 0, 0} }; @@ -39,7 +39,7 @@ int main(int argc, char *argv[]) { int option_index = 0; while(1){ - c = getopt_long (argc, argv, "abc:d:f", + c = getopt_long (argc, argv, "p:f", long_options, &option_index); if (c == -1) break; @@ -49,10 +49,10 @@ int main(int argc, char *argv[]) { case 'f': SET_FLAG(SHOW_FPS,true); break; - /*case 'c': - cvalue = optarg; - break; - */ + case 'p': + strcpy(port,optarg); + break; + case '?': /* getopt_long already printed an error message. */ @@ -63,10 +63,12 @@ int main(int argc, char *argv[]) { } } - asio::io_service io_service; - Server s(io_service, atoi(port) ); + Game game; - GameWindow window(500, 500); + asio::io_service io_service; + Server s(io_service, game.state(), atoi(port) ); + + GameWindow window(500, 500, &game); window.set_maxfps(60.0); while(window.running()){ diff --git a/game/server.hpp b/game/server.hpp index 7b6e59a..23bb4de 100644 --- a/game/server.hpp +++ b/game/server.hpp @@ -12,10 +12,11 @@ using asio::ip::tcp; class Server { public: - Server(asio::io_service& io_service, short port) + Server(asio::io_service& io_service,game::State* s, short port) : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)), socket_(io_service) { + state=s; do_accept(); } @@ -27,7 +28,7 @@ private: { if (!ec) { - std::make_shared(std::move(socket_))->start(); + std::make_shared(std::move(socket_),state)->start(); } do_accept(); @@ -36,4 +37,5 @@ private: tcp::acceptor acceptor_; tcp::socket socket_; + game::State* state; }; diff --git a/game/session.hpp b/game/session.hpp index 0c1a04e..cc7b3da 100644 --- a/game/session.hpp +++ b/game/session.hpp @@ -11,16 +11,22 @@ class Session : public std::enable_shared_from_this { public: - Session(tcp::socket socket) - : socket_(std::move(socket)) + Session(tcp::socket socket, game::State* state) + : m_socket(std::move(socket)) { + m_state = state; + char c[]="> "; + strcpy(m_snd_data, c); } void start() { + if(m_started) return; + m_started=true; + m_id = m_state->addPlayer(); auto self(shared_from_this()); - char hello[] = "\nUse \"n name\" to change name, \"v velocity\" to change velocity, \"c\" to clear past shots or \"q\" to close the connection.\nEverything else is interpreted as a shooting angle.\n\n>"; - asio::async_write(socket_, asio::buffer(hello, strlen(hello)), + char hello[] = "\nUse \"n name\" to change name, \"v velocity\" to change velocity, \"c\" to clear past shots or \"q\" to close the connection.\nEverything else is interpreted as a shooting angle.\n\n> "; + asio::async_write(m_socket, asio::buffer(hello, strlen(hello)), [this, self](std::error_code ec, std::size_t /*length*/) { if (!ec) @@ -34,7 +40,7 @@ private: void do_read() { auto self(shared_from_this()); - socket_.async_read_some(asio::buffer(data_, max_length), + m_socket.async_read_some(asio::buffer(m_rcv_data, max_length), [this, self](std::error_code ec, std::size_t length) { if (!ec) @@ -47,7 +53,7 @@ private: void do_write(std::size_t length) { auto self(shared_from_this()); - asio::async_write(socket_, asio::buffer(data_, length), + asio::async_write(m_socket, asio::buffer(m_snd_data, length), [this, self](std::error_code ec, std::size_t /*length*/) { if (!ec) @@ -57,7 +63,11 @@ private: }); } - tcp::socket socket_; + tcp::socket m_socket; enum { max_length = 1024 }; - char data_[max_length]; + char m_snd_data[max_length]; + char m_rcv_data[max_length]; + game::State* m_state; + bool m_started = false; + int m_id; }; diff --git a/game/state/state.cpp b/game/state/state.cpp index bc39594..1eb66d3 100644 --- a/game/state/state.cpp +++ b/game/state/state.cpp @@ -62,10 +62,12 @@ namespace game { return true; } - void State::addPlayer(int playerId) + int State::addPlayer() { + int playerId = m_nextId++; Player *player = new Player(playerId); players.push_back(player); + return playerId; } void State::playerLeft(int playerId) diff --git a/game/state/state.hpp b/game/state/state.hpp index 0df4313..5058ef6 100644 --- a/game/state/state.hpp +++ b/game/state/state.hpp @@ -36,7 +36,7 @@ namespace game { // The upper layer (network/renderer) calling these three functions // should keep id's unique and give one (network) input an id. - void addPlayer(int playerId); + int addPlayer(); void playerLeft(int playerId); void commandForPlayer(int playerId, Command *cmd); @@ -89,5 +89,6 @@ namespace game { float m_playerRespawnTime; float m_shipRadius; float m_defaultEnergy; + int m_nextId=0; }; }; From eaff023ed3e8485a18b916c49733d96f4b28c997 Mon Sep 17 00:00:00 2001 From: /jedi/ Date: Wed, 28 Sep 2016 03:35:05 +0200 Subject: [PATCH 11/13] networking parse command --- game/CMakeLists.txt | 2 +- game/main.cpp | 1 - game/server.hpp | 3 --- game/session.hpp | 60 ++++++++------------------------------------ game/state/state.cpp | 2 +- game/state/state.hpp | 2 +- 6 files changed, 14 insertions(+), 56 deletions(-) diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index d3995c4..b807796 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -11,7 +11,7 @@ set(GAME_SRC renderer.cpp game_window.cpp triangle_window.cpp - + session.cpp util.cpp game.cpp state/object.cpp diff --git a/game/main.cpp b/game/main.cpp index f33a738..2718363 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -10,7 +10,6 @@ uint64_t optionsFlags; - using asio::ip::tcp; using namespace std; diff --git a/game/server.hpp b/game/server.hpp index 23bb4de..dc33e08 100644 --- a/game/server.hpp +++ b/game/server.hpp @@ -1,8 +1,5 @@ #pragma once -//#include -//#include -//#include #include #include "session.hpp" diff --git a/game/session.hpp b/game/session.hpp index cc7b3da..23a8a49 100644 --- a/game/session.hpp +++ b/game/session.hpp @@ -3,8 +3,11 @@ #include #include #include +#include #include +#include "game.hpp" + using asio::ip::tcp; class Session @@ -15,59 +18,18 @@ public: : m_socket(std::move(socket)) { m_state = state; - char c[]="> "; - strcpy(m_snd_data, c); } - void start() - { - if(m_started) return; - m_started=true; - m_id = m_state->addPlayer(); - auto self(shared_from_this()); - char hello[] = "\nUse \"n name\" to change name, \"v velocity\" to change velocity, \"c\" to clear past shots or \"q\" to close the connection.\nEverything else is interpreted as a shooting angle.\n\n> "; - asio::async_write(m_socket, asio::buffer(hello, strlen(hello)), - [this, self](std::error_code ec, std::size_t /*length*/) - { - if (!ec) - { - do_read(); - } - }); - } + void start(); private: - void do_read() - { - auto self(shared_from_this()); - m_socket.async_read_some(asio::buffer(m_rcv_data, max_length), - [this, self](std::error_code ec, std::size_t length) - { - if (!ec) - { - do_write(length); - } - }); - } - - void do_write(std::size_t length) - { - auto self(shared_from_this()); - asio::async_write(m_socket, asio::buffer(m_snd_data, length), - [this, self](std::error_code ec, std::size_t /*length*/) - { - if (!ec) - { - do_read(); - } - }); - } - - tcp::socket m_socket; - enum { max_length = 1024 }; - char m_snd_data[max_length]; - char m_rcv_data[max_length]; + void do_read(); + void do_write(char m_snd_data[], std::size_t length); + bool parse(std::string); + tcp::socket m_socket; + enum { max_length = 1024 }; + char m_rcv_data[max_length]; game::State* m_state; bool m_started = false; - int m_id; + int m_pid; }; diff --git a/game/state/state.cpp b/game/state/state.cpp index 1eb66d3..acc2502 100644 --- a/game/state/state.cpp +++ b/game/state/state.cpp @@ -70,7 +70,7 @@ namespace game { return playerId; } - void State::playerLeft(int playerId) + void State::quitPlayer(int playerId) { (void) playerId; } diff --git a/game/state/state.hpp b/game/state/state.hpp index 5058ef6..a526d06 100644 --- a/game/state/state.hpp +++ b/game/state/state.hpp @@ -37,7 +37,7 @@ namespace game { // The upper layer (network/renderer) calling these three functions // should keep id's unique and give one (network) input an id. int addPlayer(); - void playerLeft(int playerId); + void quitPlayer(int playerId); void commandForPlayer(int playerId, Command *cmd); // lookup. return nullptr on invalid playerId From 8f41d89a3ca8bfaa506940de27979238519c7290 Mon Sep 17 00:00:00 2001 From: /jedi/ Date: Wed, 28 Sep 2016 03:45:59 +0200 Subject: [PATCH 12/13] fixes merge bug --- game/game_window.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/game/game_window.hpp b/game/game_window.hpp index 884a628..defd766 100644 --- a/game/game_window.hpp +++ b/game/game_window.hpp @@ -47,11 +47,11 @@ protected: drawTrace(trace); } - for (const game::Explosion *explosion : m_game.state()->explosions) { + for (const game::Explosion *explosion : m_game->state()->explosions) { drawExplosion(explosion); } - for (const game::Ship *ship : m_game.state()->ships) { + for (const game::Ship *ship : m_game->state()->ships) { drawShip(ship->position); } From 78b9b2436c59529865c1c17a7c20e320f8d6f695 Mon Sep 17 00:00:00 2001 From: /jedi/ Date: Wed, 28 Sep 2016 05:52:23 +0200 Subject: [PATCH 13/13] stuff to test --- game/game.cpp | 4 ++-- game/state/state.cpp | 26 ++++++++++++++++++++++++++ game/state/state.hpp | 4 ++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/game/game.cpp b/game/game.cpp index 0389e72..181b8ff 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -15,12 +15,11 @@ Game::Game() m_state = new game::State(); m_state->init(); - m_state->addPlayer(); } bool Game::cycle(float dt) { -#if 1 +#if 0 // XXX the following is just testing code to do things static float total = 0.0; @@ -34,6 +33,7 @@ bool Game::cycle(float dt) // m_state->players[0]->addCommand(new game::ShootCommand(a)); // } //} + m_state->addPlayer(); acc += dt; total += dt; diff --git a/game/state/state.cpp b/game/state/state.cpp index 63ef686..ae366da 100644 --- a/game/state/state.cpp +++ b/game/state/state.cpp @@ -18,6 +18,8 @@ #include "util.hpp" +using namespace std; + namespace game { void State::init() { @@ -76,6 +78,30 @@ namespace game { void State::quitPlayer(int playerId) { (void) playerId; + cout << playerId << " quit" << endl; + } + + void State::clear(int playerId) + { + cout << playerId << " clear" << endl; + } + + void State::setName(int playerId, std::string name) + { + // discard if not unique + for (const Player *other : players) { + if (name == other->name) { + std::cout << "name '" << name << "' already given to player #" << other->id << std::endl; + return; + } + } + + playerForId(playerId)->name = name; + } + + void State::setSpeed(int playerId, double speed) + { + playerForId(playerId)->speed = speed; } void State::advancePlayerShipSpawns(float dt) diff --git a/game/state/state.hpp b/game/state/state.hpp index 40c71f6..c57a849 100644 --- a/game/state/state.hpp +++ b/game/state/state.hpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -51,6 +52,9 @@ namespace game { // The upper layer (network/renderer) calling these three functions // should keep id's unique and give one (network) input an id. int addPlayer(); + void clear(int playerId); + void setName(int playerId, std::string name); + void setSpeed(int playerId, double speed); void quitPlayer(int playerId); void commandForPlayer(int playerId, Command *cmd);