merge from master
This commit is contained in:
commit
244f98178a
14 changed files with 421 additions and 79 deletions
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
Game::Game()
|
Game::Game()
|
||||||
{
|
{
|
||||||
// advance simulation with 100 Hz
|
// advance simulation in fixed steps 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_time_for_next_step = 0.0;
|
||||||
|
|
||||||
m_state = new game::State();
|
m_state = new game::State();
|
||||||
|
@ -20,23 +20,42 @@ Game::Game()
|
||||||
|
|
||||||
bool Game::cycle(float dt)
|
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;
|
static float acc = 0.0;
|
||||||
acc += dt;
|
|
||||||
|
//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;
|
float spawnInterval = 0.1;
|
||||||
while(acc > spawnInterval) {
|
while(acc > spawnInterval) {
|
||||||
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;
|
float speed = 0.005;
|
||||||
m_state->players[0]->addCommand(new game::ShootCommand(a, speed));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 1
|
m_state->players[0]->addCommand(new game::SetSpeedCommand(speed));
|
||||||
if (dt >= 10.0) {
|
m_state->players[0]->addCommand(new game::ShootCommand(angle));
|
||||||
//std::cout<<"time to big: " << dt << std::endl;
|
|
||||||
dt = m_time_step;
|
//static bool done = false;
|
||||||
|
//if (total >= 10.0 && !done) {
|
||||||
|
// done = true;
|
||||||
|
|
||||||
|
// m_state->players[0]->addCommand(new game::ClearTracesCommand());
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//std::cout<<"adding dt: " << dt << std::endl;
|
//std::cout<<"adding dt: " << dt << std::endl;
|
||||||
m_time_for_next_step += dt;
|
m_time_for_next_step += dt;
|
||||||
|
@ -53,11 +72,4 @@ bool Game::cycle(float dt)
|
||||||
//std::cout << m_time_for_next_step << " s remaining time, " << steps << " steps taken." << std::endl;
|
//std::cout << m_time_for_next_step << " s remaining time, " << steps << " steps taken." << std::endl;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
(void) dt;
|
|
||||||
|
|
||||||
m_state->advance(dt);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "state/player.hpp"
|
#include "state/player.hpp"
|
||||||
#include "state/planet.hpp"
|
#include "state/planet.hpp"
|
||||||
#include "state/ship.hpp"
|
#include "state/ship.hpp"
|
||||||
|
#include "state/explosion.hpp"
|
||||||
|
|
||||||
class GameWindow : public endofthejedi::GLWindow {
|
class GameWindow : public endofthejedi::GLWindow {
|
||||||
private:
|
private:
|
||||||
|
@ -46,7 +47,11 @@ protected:
|
||||||
drawTrace(trace);
|
drawTrace(trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const game::Ship *ship : m_game->state()->ships) {
|
for (const game::Explosion *explosion : m_game.state()->explosions) {
|
||||||
|
drawExplosion(explosion);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const game::Ship *ship : m_game.state()->ships) {
|
||||||
drawShip(ship->position);
|
drawShip(ship->position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +83,6 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawMissile(const glm::vec2 &pos)
|
void drawMissile(const glm::vec2 &pos)
|
||||||
|
|
||||||
{
|
{
|
||||||
glm::vec3 color = glm::vec3(1.0, 1.0, 0.3);
|
glm::vec3 color = glm::vec3(1.0, 1.0, 0.3);
|
||||||
m_renderer.drawCircle(pos.x, pos.y, 0.01, color.x, color.y, color.z, 6);
|
m_renderer.drawCircle(pos.x, pos.y, 0.01, color.x, color.y, color.z, 6);
|
||||||
|
@ -92,6 +96,17 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawExplosion(const game::Explosion *explosion)
|
||||||
|
{
|
||||||
|
// TODO: transparent
|
||||||
|
// TODO: with glow in the middle
|
||||||
|
float r = explosion->maxRadius * (explosion->age / explosion->maxAge);
|
||||||
|
|
||||||
|
// TODO: transparency?
|
||||||
|
glm::vec3 color = glm::vec3(1.0, 0.9, 0.1);
|
||||||
|
m_renderer.drawCircle(explosion->position.x, explosion->position.y, r, color.x, color.y, color.z, 64);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameWindow(unsigned int width, unsigned int height, Game* game)
|
GameWindow(unsigned int width, unsigned int height, Game* game)
|
||||||
: endofthejedi::GLWindow(width, height) { m_game = game; }
|
: endofthejedi::GLWindow(width, height) { m_game = game; }
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "trace.hpp"
|
#include "trace.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace game {
|
namespace game {
|
||||||
void ShootCommand::apply(Player *player, State *state) const
|
void ShootCommand::apply(Player *player, State *state) const
|
||||||
{
|
{
|
||||||
|
@ -10,23 +12,72 @@ namespace game {
|
||||||
// TODO: idea
|
// TODO: idea
|
||||||
// shoot multiple rockets at once or from different positions after
|
// shoot multiple rockets at once or from different positions after
|
||||||
// level up / upgrade ...
|
// 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);
|
Trace *trace = new Trace(missile);
|
||||||
missile->trace = trace;
|
missile->trace = trace;
|
||||||
|
|
||||||
player->energy -= m_speed;
|
player->energy -= player->speed;
|
||||||
player->missiles.push_back(missile);
|
player->missiles.push_back(missile);
|
||||||
|
|
||||||
state->addTrace(trace);
|
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;
|
(void) state;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
return player->alive && player->energy >= m_speed;
|
return player->alive && player->energy >= player->speed;
|
||||||
//return player->alive;
|
//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
|
||||||
|
{
|
||||||
|
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->player == player) {
|
||||||
|
state->deleteTrace(i);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#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
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace game {
|
namespace game {
|
||||||
|
/**
|
||||||
|
* Base class for commands.
|
||||||
|
* must derive from this.
|
||||||
|
*/
|
||||||
class Command {
|
class Command {
|
||||||
public:
|
public:
|
||||||
Command()
|
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) player;
|
||||||
(void) state;
|
(void) state;
|
||||||
|
@ -38,19 +46,95 @@ namespace game {
|
||||||
virtual std::string name() const { return "<unnamed>"; }
|
virtual std::string name() const { return "<unnamed>"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* Implemented commands */
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shoot at angle and optional speed.
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
class ShootCommand : public Command {
|
class ShootCommand : public Command {
|
||||||
public:
|
public:
|
||||||
ShootCommand(float angle, float speed) : m_angle(angle), m_speed(speed)
|
ShootCommand(float angle) : m_angle(angle)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name() const { return "<shoot>"; }
|
std::string name() const { return "<shoot>"; }
|
||||||
|
|
||||||
void apply( Player *player, State *state) const;
|
void apply( Player *player, State *state) const;
|
||||||
bool allowed(const Player *player, const State *state) const;
|
bool ready(const Player *player, const State *state) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float m_angle;
|
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 "<change name>"; }
|
||||||
|
|
||||||
|
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 "<clear traces>"; }
|
||||||
|
|
||||||
|
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 "<set speed>"; }
|
||||||
|
|
||||||
|
void apply(Player *player, State *state) const;
|
||||||
|
|
||||||
|
private:
|
||||||
float m_speed;
|
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 "<take over player>"; }
|
||||||
|
|
||||||
|
void apply( Player *player, State *state) const;
|
||||||
|
bool ready(const Player *player, const State *state) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_otherPlayerId;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,31 +2,32 @@
|
||||||
|
|
||||||
#include <glm/vec2.hpp>
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
|
#include "missile_hit_type.hpp"
|
||||||
|
|
||||||
namespace game {
|
namespace game {
|
||||||
/**
|
/**
|
||||||
* Explosion: just an effect which looks good.
|
* Explosion: just an effect which looks good.
|
||||||
*/
|
*/
|
||||||
class Explosion {
|
class Explosion {
|
||||||
public:
|
public:
|
||||||
enum class Kind {
|
Explosion(const glm::vec2 &pos, Hit hit, float maxAge=1.0)
|
||||||
MissileExplodesInSpace, // missile explode in free space
|
: hit(hit)
|
||||||
MissileAgainstPlanet, // explosion of missile when it hits a planet
|
, position(pos)
|
||||||
MissileAgainstShip // bigger explosion: missile hits a ship which explodes with it
|
, age(0.0)
|
||||||
};
|
, maxAge(maxAge * (1.0 + 0.1*util::randf_0_1()))
|
||||||
|
, maxRadius(0.05)
|
||||||
Explosion(const glm::vec2 &pos, Kind kind, float maxAge=1.0)
|
|
||||||
: position(pos), kind(kind), age(0.0), maxAge(maxAge)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const Kind kind; // kind of the explosion
|
const Hit hit; // kind of the explosion depends on the hit type
|
||||||
const glm::vec2 position; // position where it starts
|
const glm::vec2 position; // position where it starts
|
||||||
float age; // age (in seconsd) of the explosion
|
float age; // age (in seconsd) of the explosion
|
||||||
|
|
||||||
// age (in seconds) when the explosion is not visible
|
// age (in seconds) when the explosion is not visible
|
||||||
// anymore and will disappear afterwards
|
// anymore and will disappear afterwards
|
||||||
const float maxAge;
|
const float maxAge;
|
||||||
|
const float maxRadius; // current radius depends on time.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace game {
|
||||||
if (dist <= planet->radius) {
|
if (dist <= planet->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, Missile::HitObject::HitPlanet);
|
return Missile::Event(position, planet->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
dist *= 20.0;
|
dist *= 20.0;
|
||||||
|
@ -77,7 +77,7 @@ namespace game {
|
||||||
// check if distance to center of the universe is getting too big
|
// check if distance to center of the universe is getting too big
|
||||||
float distToCenter = glm::length(position);
|
float distToCenter = glm::length(position);
|
||||||
if (distToCenter > state->maxMissileDistance()) {
|
if (distToCenter > state->maxMissileDistance()) {
|
||||||
return Missile::Event(position, Missile::HitObject::LeftUniverse);
|
return Missile::Event(position, Hit::BorderOfUniverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Missile::Event(position);
|
return Missile::Event(position);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <glm/vec2.hpp>
|
#include <glm/vec2.hpp>
|
||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
|
|
||||||
|
#include "missile_hit_type.hpp"
|
||||||
|
|
||||||
namespace game {
|
namespace game {
|
||||||
class State;
|
class State;
|
||||||
class Ship;
|
class Ship;
|
||||||
|
@ -15,39 +17,42 @@ namespace game {
|
||||||
// trace then belongs to the player.
|
// trace then belongs to the player.
|
||||||
class Missile {
|
class Missile {
|
||||||
public:
|
public:
|
||||||
enum class HitObject {
|
|
||||||
Nothing,
|
|
||||||
HitPlayer,
|
|
||||||
HitPlanet,
|
|
||||||
// HitMissile,
|
|
||||||
LeftUniverse
|
|
||||||
};
|
|
||||||
|
|
||||||
// missile advances to pos. if hit != Nothing, it hits something and
|
// missile advances to pos. if hit != Nothing, it hits something and
|
||||||
// stops existing afterwards.
|
// stops existing afterwards.
|
||||||
class Event {
|
class Event {
|
||||||
public:
|
public:
|
||||||
Event(const glm::vec2 &pos) : Event(pos, HitObject::Nothing)
|
Event(const glm::vec2 &pos)
|
||||||
|
: Event(pos, Hit::Nothing)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Event(const glm::vec2 &pos, HitObject hit)
|
Event(const glm::vec2 &pos, Hit hit)
|
||||||
: hit(hit), pos(pos)
|
: hit(hit), position(pos)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Event(const glm::vec2 &pos, int planetId) : Event(pos, Hit::Planet)
|
||||||
|
{
|
||||||
|
this->planetId = planetId;
|
||||||
|
}
|
||||||
|
|
||||||
Event(const glm::vec2 &pos, int playerIdKiller, int playerIdVictim)
|
Event(const glm::vec2 &pos, int playerIdKiller, int playerIdVictim)
|
||||||
: Event(pos, HitObject::HitPlayer)
|
: Event(pos, Hit::Ship)
|
||||||
{
|
{
|
||||||
this->playerIdKiller = playerIdKiller;
|
this->playerIdKiller = playerIdKiller;
|
||||||
this->playerIdVictim = playerIdVictim;
|
this->playerIdVictim = playerIdVictim;
|
||||||
}
|
}
|
||||||
|
|
||||||
HitObject hit;
|
Hit hit;
|
||||||
glm::vec2 pos;
|
glm::vec2 position;
|
||||||
|
|
||||||
|
// if a player was hit, these are valid.
|
||||||
int playerIdKiller;
|
int playerIdKiller;
|
||||||
int playerIdVictim;
|
int playerIdVictim;
|
||||||
|
|
||||||
|
// if a planet was hit, this is valid
|
||||||
|
int planetId;
|
||||||
};
|
};
|
||||||
|
|
||||||
Missile(Player *player, const glm::vec2 &pos, float angle, float speed);
|
Missile(Player *player, const glm::vec2 &pos, float angle, float speed);
|
||||||
|
|
19
game/state/missile_hit_type.hpp
Normal file
19
game/state/missile_hit_type.hpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace game {
|
||||||
|
/*
|
||||||
|
* A missile can hit different objects the type says which one.
|
||||||
|
* Used in various places so extra file for this.
|
||||||
|
*/
|
||||||
|
enum class Hit {
|
||||||
|
Nothing,
|
||||||
|
Ship,
|
||||||
|
Planet,
|
||||||
|
|
||||||
|
// TODO could be needed for really fancy explosions because
|
||||||
|
// this is cool and should noh happen very often
|
||||||
|
// AgainstMissile,
|
||||||
|
|
||||||
|
BorderOfUniverse
|
||||||
|
};
|
||||||
|
}
|
|
@ -2,11 +2,39 @@
|
||||||
|
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace game {
|
namespace game {
|
||||||
class Planet : public Object {
|
class Planet : public Object {
|
||||||
public:
|
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, int id, float r) : Planet(pos, id, r, Material::Rock)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Planet(const glm::vec2 &pos, int id, float r, Material mat)
|
||||||
|
: Object(pos, r)
|
||||||
|
, id(id)
|
||||||
|
, material(mat)
|
||||||
|
, seed(rand())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int id;
|
||||||
|
Material material; // for rendering and physics (can fly through sun and outer gas planets)
|
||||||
|
int seed; // just for rendering variation
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -15,12 +16,14 @@ namespace game {
|
||||||
public:
|
public:
|
||||||
int id;
|
int id;
|
||||||
bool alive;
|
bool alive;
|
||||||
|
float speed;
|
||||||
float energy;
|
float energy;
|
||||||
float deadTimeCounter;
|
float deadTimeCounter;
|
||||||
Ship *ship;
|
Ship *ship;
|
||||||
|
std::string name;
|
||||||
std::vector<Missile*> missiles;
|
std::vector<Missile*> 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("<unnamed>")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
#include <glm/gtx/norm.hpp>
|
#include <glm/gtx/norm.hpp>
|
||||||
|
|
||||||
|
#include "missile_hit_type.hpp"
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
#include "missile.hpp"
|
#include "missile.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
#include "ship.hpp"
|
#include "ship.hpp"
|
||||||
#include "commands.hpp"
|
#include "commands.hpp"
|
||||||
#include "trace.hpp"
|
#include "trace.hpp"
|
||||||
|
#include "explosion.hpp"
|
||||||
|
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
|
@ -23,6 +25,7 @@ namespace game {
|
||||||
m_maxMissileDistance = 2.0;
|
m_maxMissileDistance = 2.0;
|
||||||
m_playerRespawnTime = 2.0;
|
m_playerRespawnTime = 2.0;
|
||||||
m_defaultEnergy = 10.0;
|
m_defaultEnergy = 10.0;
|
||||||
|
m_maxNumTraces = 10;
|
||||||
|
|
||||||
bool planetsOnCircle = false;
|
bool planetsOnCircle = false;
|
||||||
|
|
||||||
|
@ -43,7 +46,7 @@ namespace game {
|
||||||
}
|
}
|
||||||
} while(glm::length(pos) < 0.2 && tries++ < 1000);
|
} 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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +111,7 @@ namespace game {
|
||||||
// try to execute as much queued commands as possible.
|
// try to execute as much queued commands as possible.
|
||||||
while (player->hasCommandInQueue()) {
|
while (player->hasCommandInQueue()) {
|
||||||
Command *command = player->peekCommand();
|
Command *command = player->peekCommand();
|
||||||
if (!command->allowed(player, this)) {
|
if (!command->ready(player, this)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,12 +148,9 @@ namespace game {
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// add points
|
// add points
|
||||||
//
|
|
||||||
// TODO
|
// TODO
|
||||||
// message
|
// message
|
||||||
//
|
|
||||||
// TODO
|
|
||||||
// respawn timer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void State::advancePlayerMissiles(float dt)
|
void State::advancePlayerMissiles(float dt)
|
||||||
|
@ -164,26 +164,27 @@ 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();
|
const bool isHit = (evt.hit != Hit::Nothing);
|
||||||
|
|
||||||
// TODO:
|
if (missile->trace != nullptr) {
|
||||||
// spawn just if the path differs
|
missile->trace->addPointFromMissile(isHit); // force point if missile gets destroyed a
|
||||||
|
}
|
||||||
|
|
||||||
if (evt.hit == Missile::HitObject::Nothing) {
|
if (!isHit) {
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
switch(evt.hit) {
|
switch(evt.hit) {
|
||||||
case Missile::HitObject::HitPlanet:
|
case Hit::Planet:
|
||||||
//std::cout<<"hit Planet" << std::endl;
|
//std::cout<<"hit Planet" << std::endl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Missile::HitObject::HitPlayer:
|
case Hit::Ship:
|
||||||
//std::cout<<"hit Player" << std::endl;
|
//std::cout<<"hit Player" << std::endl;
|
||||||
playerKillsPlayer(playerForId(evt.playerIdKiller), playerForId(evt.playerIdVictim));
|
playerKillsPlayer(playerForId(evt.playerIdKiller), playerForId(evt.playerIdVictim));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Missile::HitObject::LeftUniverse:
|
case Hit::BorderOfUniverse:
|
||||||
//std::cout<<"missile left the universe." << std::endl;
|
//std::cout<<"missile left the universe." << std::endl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -191,6 +192,12 @@ namespace game {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addExplosionFromHit(&evt);
|
||||||
|
|
||||||
|
if (missile->trace != nullptr) {
|
||||||
|
missile->trace->finish();
|
||||||
|
}
|
||||||
|
|
||||||
player->missiles.erase(player->missiles.begin() + i);
|
player->missiles.erase(player->missiles.begin() + i);
|
||||||
delete(missile);
|
delete(missile);
|
||||||
//std::cout<<std::endl;
|
//std::cout<<std::endl;
|
||||||
|
@ -202,16 +209,32 @@ namespace game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void State::advanceExplosions(float dt)
|
||||||
|
{
|
||||||
|
size_t i=0;
|
||||||
|
while(i < explosions.size()) {
|
||||||
|
Explosion *explosion = explosions[i];
|
||||||
|
explosion->age += dt;
|
||||||
|
if (explosion->age >= explosion->maxAge) {
|
||||||
|
delete(explosion);
|
||||||
|
explosions.erase(explosions.begin()+i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void State::advance(float dt)
|
void State::advance(float dt)
|
||||||
{
|
{
|
||||||
//std::cout<<"advance ship spawns" << std::endl;
|
|
||||||
advancePlayerShipSpawns(dt);
|
advancePlayerShipSpawns(dt);
|
||||||
|
|
||||||
//std::cout<<"advance commands" << std::endl;
|
advanceExplosions(dt);
|
||||||
|
|
||||||
advancePlayerCommands(dt);
|
advancePlayerCommands(dt);
|
||||||
|
|
||||||
//std::cout<<"advance missiles" << std::endl;
|
|
||||||
advancePlayerMissiles(dt);
|
advancePlayerMissiles(dt);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Player *State::playerForId(int playerId)
|
Player *State::playerForId(int playerId)
|
||||||
|
@ -270,6 +293,56 @@ namespace game {
|
||||||
|
|
||||||
void State::addTrace(Trace *trace)
|
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);
|
traces.push_back(trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void State::deleteTrace(size_t index)
|
||||||
|
{
|
||||||
|
if (index >= 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)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
while(i < traces.size()) {
|
||||||
|
if (traces[i] == trace) {
|
||||||
|
deleteTrace(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void State::addExplosionFromHit(const Missile::Event *evt)
|
||||||
|
{
|
||||||
|
if (evt->hit == Hit::Nothing || evt->hit == Hit::BorderOfUniverse) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
explosions.push_back(new Explosion(evt->position, evt->hit));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,28 @@
|
||||||
|
|
||||||
#include <glm/vec2.hpp>
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
|
#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 {
|
namespace game {
|
||||||
// forward declarations
|
// forward declarations
|
||||||
class Command;
|
class Command;
|
||||||
class Missile;
|
|
||||||
class Player;
|
class Player;
|
||||||
class Planet;
|
class Planet;
|
||||||
class Ship;
|
class Ship;
|
||||||
class Trace;
|
class Trace;
|
||||||
|
class Explosion;
|
||||||
|
|
||||||
class State {
|
class State {
|
||||||
public:
|
public:
|
||||||
|
@ -55,16 +69,21 @@ namespace game {
|
||||||
// add a trace to the list of traces.
|
// add a trace to the list of traces.
|
||||||
void addTrace(Trace *trace);
|
void addTrace(Trace *trace);
|
||||||
|
|
||||||
|
// delete traces with this command
|
||||||
|
void deleteTrace(Trace *trace); // using a pointer
|
||||||
|
void deleteTrace(size_t index); // using an index
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* Rendering */
|
/* Rendering */
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
// Game items which should be rendered are here:
|
// Game items which should be rendered are here:
|
||||||
// (access missiles by iterating over player's missiles attribute)
|
// (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;
|
std::vector<Trace*> traces;
|
||||||
|
std::vector<Explosion*> explosions;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
@ -73,6 +92,9 @@ namespace game {
|
||||||
|
|
||||||
void playerKillsPlayer(Player *killer, Player *victim);
|
void playerKillsPlayer(Player *killer, Player *victim);
|
||||||
|
|
||||||
|
void addExplosionFromHit(const Missile::Event *evt);
|
||||||
|
|
||||||
|
void advanceExplosions(float dt);
|
||||||
void advancePlayerShipSpawns(float dt);
|
void advancePlayerShipSpawns(float dt);
|
||||||
void advancePlayerCommands(float dt);
|
void advancePlayerCommands(float dt);
|
||||||
void advancePlayerMissiles(float dt);
|
void advancePlayerMissiles(float dt);
|
||||||
|
@ -90,5 +112,6 @@ namespace game {
|
||||||
float m_shipRadius;
|
float m_shipRadius;
|
||||||
float m_defaultEnergy;
|
float m_defaultEnergy;
|
||||||
int m_nextId=0;
|
int m_nextId=0;
|
||||||
|
int m_maxNumTraces;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "missile.hpp"
|
#include "missile.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace game {
|
namespace game {
|
||||||
Trace::TracePoint::TracePoint(const Missile *missile)
|
Trace::TracePoint::TracePoint(const Missile *missile)
|
||||||
: position(missile->position)
|
: 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));
|
points.push_back(TracePoint(missile));
|
||||||
}
|
}
|
||||||
|
@ -24,4 +35,10 @@ namespace game {
|
||||||
points.push_back(TracePoint(missile));
|
points.push_back(TracePoint(missile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Trace::finish()
|
||||||
|
{
|
||||||
|
//std::cout<<"trace finished now!" << std::endl;
|
||||||
|
missile = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
namespace game {
|
namespace game {
|
||||||
class Missile;
|
class Missile;
|
||||||
|
class Player;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Trace of a missile through the space.
|
* Trace of a missile through the space.
|
||||||
|
@ -12,7 +13,8 @@ namespace game {
|
||||||
*/
|
*/
|
||||||
class Trace {
|
class Trace {
|
||||||
public:
|
public:
|
||||||
Trace(const Missile *missile);
|
Trace(Missile *missile);
|
||||||
|
~Trace();
|
||||||
|
|
||||||
// Add the current position of the missile as a new point on the
|
// Add the current position of the missile as a new point on the
|
||||||
// trace.
|
// trace.
|
||||||
|
@ -21,6 +23,10 @@ namespace game {
|
||||||
// the missile) in case the fidelityCounter would skip the current position.
|
// the missile) in case the fidelityCounter would skip the current position.
|
||||||
void addPointFromMissile(bool forceAdd=false);
|
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 /
|
// TODO: add extendLastPointToPosition() method for saving points /
|
||||||
// optimization later on
|
// optimization later on
|
||||||
|
|
||||||
|
@ -35,11 +41,16 @@ namespace game {
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<TracePoint> points;
|
std::vector<TracePoint> 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.
|
// counter which is incremented each time addPointFromMissile() is called.
|
||||||
// when reaching a certain value the point is saved for
|
// when reaching a certain value the point is saved for
|
||||||
// optimization.
|
// optimization.
|
||||||
int fidelityCounter;
|
int fidelityCounter;
|
||||||
|
|
||||||
|
// age of the trace. if too old, it can be removed to save
|
||||||
|
// space/power
|
||||||
|
float age;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue