traces are now managed by state/missile code.

This commit is contained in:
Andreas Ortmann 2016-09-27 20:13:09 +02:00
parent 2e62324815
commit fd8d56bf95
9 changed files with 109 additions and 38 deletions

View file

@ -7,6 +7,7 @@ function(setup_target NAME)
set_property(TARGET ${NAME} PROPERTY CXX_STANDARD 14) set_property(TARGET ${NAME} PROPERTY CXX_STANDARD 14)
set_property(TARGET ${NAME} PROPERTY CXX_STANDARD_REQUIRED ON) set_property(TARGET ${NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
target_compile_options(${NAME} PRIVATE -Wall -Wextra) target_compile_options(${NAME} PRIVATE -Wall -Wextra)
target_compile_options(${NAME} PRIVATE -fdiagnostics-color=always)
target_compile_options(${NAME} PRIVATE $<$<CONFIG:DEBUG>:-ggdb -O2>) target_compile_options(${NAME} PRIVATE $<$<CONFIG:DEBUG>:-ggdb -O2>)
target_compile_options(${NAME} PRIVATE $<$<CONFIG:RELEASE>:-O3 -NDEBUG>) target_compile_options(${NAME} PRIVATE $<$<CONFIG:RELEASE>:-O3 -NDEBUG>)
endfunction(setup_target) endfunction(setup_target)

View file

@ -5,6 +5,9 @@
#include "game_window.hpp" #include "game_window.hpp"
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {
(void) argv;
(void) argc;
GameWindow window(500, 500); GameWindow window(500, 500);
window.set_maxfps(60.0); window.set_maxfps(60.0);
window.loop(); window.loop();

View file

@ -1,14 +1,24 @@
#include "commands.hpp" #include "commands.hpp"
#include "trace.hpp"
namespace game { namespace game {
void ShootCommand::apply(Player *player, State *state) const void ShootCommand::apply(Player *player, State *state) const
{ {
(void) state;
// TODO spawn missile if alive and enough energy
//std::cout<<"apply command " << name() << std::endl; //std::cout<<"apply command " << name() << std::endl;
// 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);
Trace *trace = new Trace(missile);
missile->trace = trace;
player->energy -= m_speed; player->energy -= m_speed;
player->missiles.push_back(new Missile(player->id, player->ship->position, m_angle, m_speed)); player->missiles.push_back(missile);
state->addTrace(trace);
} }
bool ShootCommand::allowed(const Player *player, const State *state) const bool ShootCommand::allowed(const Player *player, const State *state) const

View file

@ -4,12 +4,15 @@
#include "state.hpp" #include "state.hpp"
#include "player.hpp" #include "player.hpp"
#include "ship.hpp"
#include "planet.hpp"
#include "trace.hpp"
#include <glm/gtx/norm.hpp> #include <glm/gtx/norm.hpp>
namespace game { namespace game {
Missile::Missile(int playerId, const glm::vec2 &pos, float angle, float speed) Missile::Missile(Player *player, const glm::vec2 &pos, float angle, float speed)
: playerId(playerId) : player(player)
, position(pos) , position(pos)
{ {
velocity = speed * glm::vec2(std::sin(angle), std::cos(angle)); velocity = speed * glm::vec2(std::sin(angle), std::cos(angle));
@ -28,13 +31,13 @@ namespace game {
glm::vec2 gravityForce = glm::vec2(0.0, 0.0); glm::vec2 gravityForce = glm::vec2(0.0, 0.0);
for (const Player *other : state->players) { for (const Player *other : state->players) {
if (other->ship != nullptr && other->id != playerId) { if (other->ship != nullptr && other != player) {
glm::vec2 diff = other->ship->position - position; glm::vec2 diff = other->ship->position - position;
float dist = glm::length(diff); float dist = glm::length(diff);
if (dist <= other->ship->radius) { if (dist <= other->ship->radius) {
// TODO: collect all hits and return the first one only // TODO: collect all hits and return the first one only
// TODO: find exact hit position! // TODO: find exact hit position!
return Missile::Event(position, playerId, other->id); return Missile::Event(position, player->id, other->id);
} }
} }
} }

View file

@ -3,13 +3,13 @@
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
#include "state.hpp"
#include "ship.hpp"
#include "planet.hpp"
namespace game { namespace game {
class State; class State;
class Ship;
class Planet;
class Player;
class State;
class Trace;
// missile belongs to a player and optionally fills a trace behind it. // missile belongs to a player and optionally fills a trace behind it.
// trace then belongs to the player. // trace then belongs to the player.
@ -50,19 +50,17 @@ namespace game {
int playerIdVictim; int playerIdVictim;
}; };
// XXX Missile(Player *player, const glm::vec2 &pos, float angle, float speed);
int playerId; // owner won't be hit by own missiles
glm::vec2 position;
glm::vec2 velocity;
//Trace *trace;
Missile(int playerId, const glm::vec2 &pos, float angle, float speed);
~Missile(); ~Missile();
// try to advance. if something will be hit, return the first hit in // try to advance. if something will be hit, return the first hit in
// time. // time.
Missile::Event advance(const game::State *state, float dt); Missile::Event advance(const game::State *state, float dt);
Player *player; // owner won't be hit by own missiles
glm::vec2 position;
glm::vec2 velocity;
Trace *trace;
}; };
} }

View file

@ -12,6 +12,7 @@
#include "planet.hpp" #include "planet.hpp"
#include "ship.hpp" #include "ship.hpp"
#include "commands.hpp" #include "commands.hpp"
#include "trace.hpp"
#include "util.hpp" #include "util.hpp"
@ -161,6 +162,11 @@ namespace game {
//std::cout<<"missile: " << (long unsigned int) missile << std::endl; //std::cout<<"missile: " << (long unsigned int) missile << std::endl;
const Missile::Event evt = missile->advance(this, dt); const Missile::Event evt = missile->advance(this, dt);
missile->trace->addPointFromMissile();
// TODO:
// spawn just if the path differs
if (evt.hit == Missile::HitObject::Nothing) { if (evt.hit == Missile::HitObject::Nothing) {
i++; i++;
@ -259,4 +265,9 @@ namespace game {
player->addCommand(cmd); player->addCommand(cmd);
} }
} }
void State::addTrace(Trace *trace)
{
traces.push_back(trace);
}
} }

View file

@ -8,25 +8,34 @@
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
namespace game { namespace game {
// forward declarations
class Command; class Command;
class Missile; class Missile;
class Player; class Player;
class Planet; class Planet;
class Ship; class Ship;
class Trace;
// trace of a missile. exists without a missile at player.
//class Trace {
//public:
// std::vector<glm::vec2> points;
//};
class State { class State {
public: public:
/*************************************************************************/
/* State management */
/*************************************************************************/
// called to setup the state (randomize planets, kill
// traces/missiles/ships etc.)
void init(); void init();
// main method to advance the simulation by the given timestamp in
// seconds.
void advance(float dt); void advance(float dt);
// the (network) layer calling these three functions should keep id's /*************************************************************************/
// unique and give one (network) input an id. /* Network / Input */
/*************************************************************************/
// 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); void addPlayer(int playerId);
void playerLeft(int playerId); void playerLeft(int playerId);
void commandForPlayer(int playerId, Command *cmd); void commandForPlayer(int playerId, Command *cmd);
@ -34,14 +43,34 @@ namespace game {
// lookup. return nullptr on invalid playerId // lookup. return nullptr on invalid playerId
Player *playerForId(int playerId); Player *playerForId(int playerId);
/*************************************************************************/
/* Mixed stuff */
// distance after which missiles get lost in space (and explode)
float maxMissileDistance() const { return m_maxMissileDistance; } float maxMissileDistance() const { return m_maxMissileDistance; }
// each ship has the same radius
float shipRadius() const { return m_shipRadius; } float shipRadius() const { return m_shipRadius; }
// add a trace to the list of traces.
void addTrace(Trace *trace);
/*************************************************************************/
/* Rendering */
/*************************************************************************/
// Game items which should be rendered are here:
// (access missiles by iterating over player's missiles attribute)
std::vector<Planet*> planets; std::vector<Planet*> planets;
std::vector<Ship*> ships; std::vector<Ship*> ships;
std::vector<Player*> players; std::vector<Player*> players;
std::vector<Trace*> traces;
private: private:
/*************************************************************************/
/* Internal */
/*************************************************************************/
void playerKillsPlayer(Player *killer, Player *victim); void playerKillsPlayer(Player *killer, Player *victim);
void advancePlayerShipSpawns(float dt); void advancePlayerShipSpawns(float dt);

View file

@ -6,17 +6,22 @@
namespace game { namespace game {
Trace::TracePoint::TracePoint(const Missile *missile) Trace::TracePoint::TracePoint(const Missile *missile)
: position(missile->position), speed(glm::length(missile->velocity)) : position(missile->position)
, speed(glm::length(missile->velocity))
{ {
} }
Trace::Trace(const Missile *missile) Trace::Trace(const Missile *missile) : missile(missile), fidelityCounter(0)
{ {
points.push_back(TracePoint(missile)); points.push_back(TracePoint(missile));
} }
void Trace::addPointFromMissile(const Missile *missile) void Trace::addPointFromMissile(bool forceAdd)
{ {
fidelityCounter++;
if (forceAdd || fidelityCounter >= 20) {
fidelityCounter = 0;
points.push_back(TracePoint(missile)); points.push_back(TracePoint(missile));
} }
}
} }

View file

@ -14,10 +14,15 @@ namespace game {
public: public:
Trace(const Missile *missile); Trace(const Missile *missile);
// TODO: add velocity of the rocket or age at the points too becasue // Add the current position of the missile as a new point on the
// that enables nice rendering of speed etc. at different points // trace.
// TODO: give missile to this // Parameters:
void addPointFromMissile(const Missile *missile); // forceAdd: set to true to add this point (good for the endpoint of
// the missile) in case the fidelityCounter would skip the current position.
void addPointFromMissile(bool forceAdd=false);
// TODO: add extendLastPointToPosition() method for saving points /
// optimization later on
/* /*
* Trace point data to be used when rendering. * Trace point data to be used when rendering.
@ -25,10 +30,16 @@ namespace game {
struct TracePoint { struct TracePoint {
TracePoint(const Missile *missile); TracePoint(const Missile *missile);
const glm::vec2 position; glm::vec2 position;
const float speed; float speed;
}; };
std::vector<TracePoint> points; std::vector<TracePoint> points;
const Missile *missile; // missile which creates this path.
// counter which is incremented each time addPointFromMissile() is called.
// when reaching a certain value the point is saved for
// optimization.
int fidelityCounter;
}; };
} }