event stuff working again. a bit too much boiler plate code but functionality counts.

This commit is contained in:
Andreas Ortmann 2016-10-03 13:37:49 +02:00
parent 2d0608b205
commit becf8602d7
18 changed files with 235 additions and 149 deletions

View file

@ -36,7 +36,7 @@ void main()
int i;
for (i=0; i<explLightsNum; i++) {
vec3 explLightColor = vec3(1.0, 0.8, 0.3);
vec3 explLightColor = vec3(1.0, 0.5, 0.2);
vec3 diff = vertex - explLightsPos[i];
float l = 10.0*length(diff);
float dir = max(0.0, -dot(normal, diff));

View file

@ -107,13 +107,13 @@ int main(int argc, char *argv[])
window.poll();
io_service.poll();
size_t numEvents = game.state()->currentStateUpdateEvents().size();
if (numEvents != 0) {
std::cout<<"game state update events: " << numEvents << std::endl;
for (game::StateUpdateEvent *evt : game.state()->currentStateUpdateEvents()) {
std::cout<< evt->description() << std::endl;
}
}
//size_t numEvents = game.state()->currentStateUpdateEvents().size();
//if (numEvents != 0) {
// std::cout<<"game state update events: " << numEvents << std::endl;
// for (game::StateUpdateEvent *evt : game.state()->currentStateUpdateEvents()) {
// std::cout<< evt->description() << std::endl;
// }
//}
//if (sounds != nullptr) {
// sounds.advance(game->state());

View file

@ -3,6 +3,8 @@
#include <iostream>
#include "state/events/explosion_event.hpp"
#include "state/events/missile_event.hpp"
#include "state/events/ship_event.hpp"
namespace endofthejedi {
void RendererPolygon3d::setup()
@ -51,9 +53,10 @@ namespace endofthejedi {
// TODO: add dust particles
// TODO: add little rocks flying around
//glClearColor(0.0, 0.0, 0.0, 1.0);
float s = 0.1;
glClearColor(s, s, 1.2*s, 1.0);
glClearColor(0.0, 0.0, 0.0, 1.0);
//float s = 0.1;
//glClearColor(s, s, 1.2*s, 1.0);
m_shader_game_objects.bind();
@ -272,19 +275,46 @@ namespace endofthejedi {
}
#endif
for (game::StateUpdateEvent *evt : m_state->currentStateUpdateEvents()) {
if (evt->eventType() == game::StateUpdateEvent::EventType::Explosion) {
auto cycle = evt->lifeCycle();
if (cycle == game::StateUpdateEvent::LifeCycle::Create) {
for (auto *evt : m_state->currentStateUpdateEvents()) {
auto type = evt->eventType();
auto cycle = evt->lifeCycle();
if (type == game::EventType::Explosion) {
if (cycle == game::LifeCycle::Create) {
game::ExplosionEvent *ee = static_cast<game::ExplosionEvent*>(evt);
const game::Explosion *expl = ee->explosion;
game::Explosion *expl = static_cast<game::Explosion*>(ee->object());
addExplosionEffect(
expl->id, expl->position,
expl->missileVelocity,
(expl->hit == game::Hit::Planet),
1000, 1.0);
}
} else if (type == game::EventType::Ship) {
game::ShipEvent *me = static_cast<game::ShipEvent*>(evt);
game::Ship *ship = static_cast<game::Ship*>(me->object());
std::cout<<"adding [graphic] explosion for #" << expl->id << std::endl;
// is always modificated
if (cycle == game::LifeCycle::Create) {
//std::cout<<"[renderer] adding missile #" << missile->id << std::endl;
m_ships.push_back(ship);
} else if (cycle == game::LifeCycle::Destroy) {
//std::cout<<"[renderer] removing missile #" << missile->id << std::endl;
m_ships.remove(ship);
}
} else if (type == game::EventType::Missile) {
game::MissileEvent *me = static_cast<game::MissileEvent*>(evt);
game::Missile *missile = static_cast<game::Missile*>(me->object());
// is always modificated
if (cycle == game::LifeCycle::Create) {
//std::cout<<"[renderer] adding missile #" << missile->id << std::endl;
m_missiles.push_back(missile);
} else if (cycle == game::LifeCycle::Destroy) {
//std::cout<<"[renderer] removing missile #" << missile->id << std::endl;
m_missiles.remove(missile);
}
}
}
@ -333,16 +363,16 @@ namespace endofthejedi {
m_missileModel->bind();
for (const game::Player *player : m_state->players) {
for (const game::Missile *missile : player->missiles) {
glm::vec3 c = glm::vec3(1.0, 1.0, 0.3);
glUniform3f(m_shader_game_objects.location("materialColor"), c.x, c.y, c.z);
for (const game::Missile *missile : m_missiles) {
glm::vec3 c = glm::vec3(1.0, 1.0, 0.3);
glUniform3f(m_shader_game_objects.location("materialColor"), c.x, c.y, c.z);
glm::mat4 model = computeModelMatrix(missile);
glUniformMatrix4fv(m_shader_game_objects.location("model"), 1, GL_FALSE, glm::value_ptr(model));
// TODO: rename functions so their name represents what args they
// take
glm::mat4 model = computeModelMatrix(missile);
glUniformMatrix4fv(m_shader_game_objects.location("model"), 1, GL_FALSE, glm::value_ptr(model));
m_missileModel->render();
}
m_missileModel->render();
}
}
@ -350,7 +380,7 @@ namespace endofthejedi {
{
m_shipModel->bind();
for (const game::Ship *ship : m_state->ships) {
for (const game::Ship *ship : m_ships) {
glm::mat4 model = computeModelMatrix(ship);
glUniformMatrix4fv(m_shader_game_objects.location("model"), 1, GL_FALSE, glm::value_ptr(model));

View file

@ -83,5 +83,9 @@ namespace endofthejedi {
float m_lastTime;
float m_aspectRatio;
// TODO: put representation specialized for rendering in here
std::list<const game::Missile*> m_missiles;
std::list<const game::Ship*> m_ships;
};
}

View file

@ -6,16 +6,9 @@
namespace game {
class ExplosionEvent : public StateUpdateEvent {
public:
ExplosionEvent(StateUpdateEvent::LifeCycle lifeCycle, Explosion *explosion)
: StateUpdateEvent(lifeCycle, StateUpdateEvent::EventType::Explosion)
, explosion(explosion)
ExplosionEvent(LifeCycle lifeCycle, Explosion *explosion)
: StateUpdateEvent(lifeCycle, EventType::Explosion, explosion)
{
std::string typeStr = StateUpdateEvent::lifeCycleToString(lifeCycle);
std::cout<<"created explosion event for id " << explosion->id << " of type " << typeStr << std::endl;
}
public:
const Explosion *explosion;
};
}

View file

@ -0,0 +1,14 @@
#pragma once
#include "state/missile.hpp"
#include "state/state_update_event.hpp"
namespace game {
class MissileEvent : public StateUpdateEvent {
public:
MissileEvent(LifeCycle lifeCycle, Missile *missile)
: StateUpdateEvent(lifeCycle, EventType::Missile, missile)
{
}
};
}

View file

@ -0,0 +1,14 @@
#pragma once
#include "state/ship.hpp"
#include "state/state_update_event.hpp"
namespace game {
class ShipEvent : public StateUpdateEvent {
public:
ShipEvent(LifeCycle lifeCycle, Ship *ship)
: StateUpdateEvent(lifeCycle, EventType::Ship, ship)
{
}
};
}

View file

@ -4,9 +4,8 @@ namespace game {
size_t s_id_counter = 0;
Explosion::Explosion(size_t id, const glm::vec2 &pos, const glm::vec2 &missileVelocity, Hit hit, float maxAge)
: id(id)
: Object(id, pos)
, hit(hit)
, position(pos)
, missileVelocity(missileVelocity)
, age(0.0)
, maxAge(maxAge * (1.0 + 0.1*util::randf_0_1()))

View file

@ -1,6 +1,6 @@
#pragma once
#include <glm/vec2.hpp>
#include "object.hpp"
#include "util.hpp"
@ -10,13 +10,11 @@ namespace game {
/**
* Explosion: just an effect which looks good.
*/
class Explosion {
class Explosion : public Object {
public:
Explosion(size_t id, const glm::vec2 &pos, const glm::vec2 &missileVelocity, Hit hit, float maxAge=1.0);
const size_t id;
const Hit hit; // kind of the explosion depends on the hit type
const glm::vec2 position; // position where it starts
const glm::vec2 missileVelocity; // impact velocity of the missile
float age; // age (in seconsd) of the explosion
@ -24,5 +22,7 @@ namespace game {
// anymore and will disappear afterwards
const float maxAge;
const float maxRadius; // current radius depends on time.
//virtual void test() = 0;
};
}

View file

@ -12,9 +12,8 @@
namespace game {
Missile::Missile(size_t id, Player *player, const glm::vec2 &pos, float angle, float speed)
: id(id)
: Object(id, pos)
, player(player)
, position(pos)
{
velocity = speed * glm::vec2(std::sin(angle), std::cos(angle));

View file

@ -1,7 +1,8 @@
#pragma once
#include "object.hpp"
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include "missile_hit_type.hpp"
@ -15,7 +16,7 @@ namespace game {
// missile belongs to a player and optionally fills a trace behind it.
// trace then belongs to the player.
class Missile {
class Missile : public Object {
public:
// missile advances to pos. if hit != Nothing, it hits something and
@ -32,13 +33,13 @@ namespace game {
{
}
Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity, int planetId)
Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity, size_t planetId)
: Event(pos, missileVelocity, Hit::Planet)
{
this->planetId = planetId;
}
Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity, int playerIdKiller, int playerIdVictim)
Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity, size_t playerIdKiller, size_t playerIdVictim)
: Event(pos, missileVelocity, Hit::Ship)
{
this->playerIdKiller = playerIdKiller;
@ -50,11 +51,11 @@ namespace game {
glm::vec2 missileVelocity;
// if a player was hit, these are valid.
int playerIdKiller;
int playerIdVictim;
size_t playerIdKiller;
size_t playerIdVictim;
// if a planet was hit, this is valid
int planetId;
size_t planetId;
};
Missile(size_t id, Player *player, const glm::vec2 &pos, float angle, float speed);
@ -64,9 +65,7 @@ namespace game {
// time.
Missile::Event advance(const game::State *state, float dt);
const size_t id;
Player *player; // owner won't be hit by own missiles
glm::vec2 position;
glm::vec2 velocity;
Trace *trace;
};

View file

@ -3,13 +3,14 @@
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
class Object {
public:
Object(const glm::vec2 &pos, float r) : position(pos), radius(r)
{
}
const glm::vec2 position;
const float radius;
};
namespace game {
class Object {
public:
Object(size_t id, const glm::vec2 &pos) : id(id), position(pos)
{
}
const size_t id;
glm::vec2 position;
};
}

View file

@ -13,24 +13,18 @@ class Planet : public Object {
*/
enum class Material { Rock=0, Metal=1, Sand=2, Gas=3, Ice=4, Water=5, Sun=6 };
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())
Planet(size_t id, const glm::vec2 &pos, float r, Material mat=Material::Rock)
: Object(id, pos), material(mat), radius(r), seed(rand())
{
}
glm::vec3 getColor() const;
int id;
// for rendering and physics (can fly through sun and outer gas planets)
Material material;
// just for rendering variation
int seed;
float radius;
int seed;
};
}

View file

@ -5,8 +5,10 @@
namespace game {
class Ship : public Object {
public:
Ship(const glm::vec2 &pos, float r) : Object(pos, r)
Ship(size_t id, const glm::vec2 &pos, float r) : Object(id, pos), radius(r)
{
}
float radius;
};
}

View file

@ -15,24 +15,26 @@
#include "trace.hpp"
#include "explosion.hpp"
#include "state_update_event.hpp"
#include "events/explosion_event.hpp"
#include "events/missile_event.hpp"
#include "events/ship_event.hpp"
#include "util.hpp"
namespace game {
void State::init(int numPlanets, bool devMode)
{
// clear
for (Planet *planet : planets) {
delete(planet);
}
planets.clear();
//for (Player *player : players) {
//}
// TODO: clear shots etc. too
m_nextPlayerId = 0;
m_nextPlayerId = 0;
m_nextMissileId = 0;
m_nextShipId = 0;
m_time = 0.0;
m_shipRadius = 0.02;
m_maxMissileDistance = 2.0;
@ -107,7 +109,7 @@ namespace game {
glm::vec2 pos;
if (findPlanetSpawnPosition(mat == Planet::Material::Sun, radius, &pos)) {
planets.push_back(new Planet(pos, i, radius, mat));
planets.push_back(new Planet(i, pos, radius, mat));
}
}
}
@ -142,20 +144,22 @@ namespace game {
return false;
}
player->ship = new Ship(spawnPos, m_shipRadius);
ships.push_back(player->ship);
Ship *ship = new Ship(m_nextShipId++, spawnPos, m_shipRadius);
player->ship = ship;
ships.push_back(ship);
player->energy = m_defaultEnergy;
addShip(ship);
return true;
}
size_t State::addPlayer()
{
size_t playerId = m_nextPlayerId++;
Player *player = new Player(playerId);
Player *player = new Player(m_nextPlayerId++);
players.push_back(player);
return playerId;
return player->id;
}
void State::quitPlayer(size_t playerId)
@ -190,6 +194,11 @@ namespace game {
playerForId(playerId)->name = name;
}
void State::addShip(Ship *ship)
{
m_nextEvents.push_back(new ShipEvent(LifeCycle::Create, ship));
}
void State::setSpeed(size_t playerId, double speed)
{
playerForId(playerId)->speed = speed;
@ -271,10 +280,7 @@ namespace game {
std::vector<Missile*> rm;
for (Missile *missile : player->missiles) {
//std::cout<<"missile: " << (long unsigned int) missile << std::endl;
const Missile::Event evt = missile->advance(this, dt);
const bool isHit = (evt.hit != Hit::Nothing);
if (missile->trace != nullptr) {
@ -324,7 +330,8 @@ namespace game {
for (Missile *missile : rm) {
player->missiles.remove(missile);
delete(missile);
m_nextEvents.push_back(new MissileEvent(LifeCycle::Destroy, missile));
}
}
}
@ -342,7 +349,9 @@ namespace game {
for (Explosion *explosion : rm) {
explosions.remove(explosion);
m_nextEvents.push_back(new ExplosionEvent(StateUpdateEvent::LifeCycle::Destroy, explosion));
m_nextEvents.push_back(new ExplosionEvent(LifeCycle::Destroy, explosion));
//delete(explosion);
}
}
@ -367,7 +376,7 @@ namespace game {
// put collected events into that list.
//m_allEvents.push_back(std::move(m_nextEvents));
for (StateUpdateEvent *evt : m_nextEvents) {
for (auto *evt : m_nextEvents) {
m_allEvents.push_back(evt);
}
m_nextEvents.clear();
@ -452,6 +461,8 @@ namespace game {
missile->trace = trace;
addTrace(trace);
m_nextEvents.push_back(new MissileEvent(LifeCycle::Create, missile));
}
void State::deleteTrace(Trace *trace)
@ -471,10 +482,13 @@ namespace game {
return;
}
Explosion *explosion = new Explosion(m_nextExplosionId++, evt->position, evt->missileVelocity, evt->hit);
Explosion *explosion = new Explosion(
m_nextExplosionId++, evt->position,
evt->missileVelocity, evt->hit);
explosions.push_back(explosion);
m_nextEvents.push_back(new ExplosionEvent(StateUpdateEvent::LifeCycle::Create, explosion));
m_nextEvents.push_back(new ExplosionEvent(LifeCycle::Create, explosion));
}
void State::advanceTraceAges(float dt)
@ -512,29 +526,29 @@ namespace game {
void State::applyAndClearAllOldStateUpdates()
{
// TODO: delete the items for events that are to be removed in proper
// way
//for (std::list<StateUpdateEvent*> list : m_allEvents) {
// for (StateUpdateEvent *evt : list) {
// delete(evt);
// }
// list.clear();
//}
for (StateUpdateEvent *evt : m_allEvents) {
if (evt->lifeCycle() == StateUpdateEvent::LifeCycle::Destroy) {
for (auto *evt : m_allEvents) {
if (evt->lifeCycle() == LifeCycle::Destroy) {
switch(evt->eventType()) {
case StateUpdateEvent::EventType::Explosion:
case EventType::Explosion:
{
ExplosionEvent *ee = static_cast<ExplosionEvent*>(evt);
std::cout<<"got explosion delete event, finally deleting explosion #"
<< ee->explosion->id << std::endl;
//std::cout<<"got explosion delete event, finally deleting explosion #"
// << ee->explosion->id << std::endl;
delete(ee->explosion);
delete(ee->object());
}
break;
case EventType::Missile:
{
auto *me = static_cast<MissileEvent*>(evt);
//std::cout<<"got missile delete event, finally deleting missile #"
// << me->missile->id << std::endl;
delete(me->object());
}
break;
default:
std::cout<<"warning: unhandled deletion event for: event type "
<< (int) evt->eventType() << std::endl;
@ -546,7 +560,7 @@ namespace game {
m_allEvents.clear();
}
std::list<StateUpdateEvent*> State::currentStateUpdateEvents() const
const std::list<StateUpdateEvent*> &State::currentStateUpdateEvents() const
{
return m_allEvents;
}

View file

@ -12,6 +12,8 @@
#include "missile.hpp"
#include "planet.hpp"
#include "state_update_event.hpp"
// TODO:
// give points for equipment / better weapons / more energy when:
// - player discovers the universe
@ -28,7 +30,6 @@ namespace game {
// forward declarations
class Command;
class Player;
class StateUpdateEvent;
class Ship;
class Trace;
@ -73,12 +74,15 @@ namespace game {
// each ship has the same radius
float shipRadius() const { return m_shipRadius; }
// add a trace to the list of traces.
// add a trace to the state
void addTrace(Trace *trace);
// add a missile
// add a missile to the state
void addMissile(Missile *missile);
// add a ship to the state
void addShip(Ship *ship);
// delete traces with this command
void deleteTrace(Trace *trace); // using a pointer
@ -105,7 +109,9 @@ namespace game {
void applyAndClearAllOldStateUpdates();
std::list<StateUpdateEvent*> currentStateUpdateEvents() const;
// delete the items for events that are to be removed in proper way
// after the events were given to other parts of the application.
const std::list<StateUpdateEvent*> &currentStateUpdateEvents() const;
/*************************************************************************/
@ -156,14 +162,14 @@ namespace game {
size_t m_nextPlayerId;
size_t m_nextExplosionId;
size_t m_nextMissileId;
size_t m_nextShipId;
float m_time;
bool m_developerMode;
glm::vec2 m_playingFieldCenter;
glm::vec2 m_playingFieldSize;
std::list<StateUpdateEvent*> m_nextEvents;
std::list<StateUpdateEvent*> m_allEvents;
//std::vector<std::list<StateUpdateEvent*>> m_allEvents;
std::list<StateUpdateEvent*> m_nextEvents;
std::list<StateUpdateEvent*> m_allEvents;
};
}

View file

@ -2,58 +2,72 @@
#include <string>
#include "object.hpp"
// TODO: make life cycle object class.
// objects from that class can be created and destroyed only through factory
// methods which create updates too.
namespace game {
enum class LifeCycle {
Create, // something was created
Modify, // something was modified (look at attributes)
Destroy // something was destroyed
};
// add all possible classes here
// TODO:
// there can be different things in here, like:
enum class EventType {
Explosion,
Missile,
Ship
};
class StateUpdateEvent {
public:
enum class LifeCycle {
Create, // something was created
Modify, // something was modified (look at attributes)
Destroy // something was destroyed
};
// add all possible classes here
enum class EventType {
Explosion
};
StateUpdateEvent(LifeCycle cycle, EventType event)
StateUpdateEvent(LifeCycle cycle, EventType event, Object *object, bool changesContinuously=false)
: m_lifeCycle(cycle), m_eventType(event)
, m_object(object)
, m_changesContinuously(changesContinuously)
{
}
LifeCycle lifeCycle() const { return m_lifeCycle; }
EventType eventType() const { return m_eventType; }
LifeCycle lifeCycle() const { return m_lifeCycle; }
EventType eventType() const { return m_eventType; }
bool changesContinuously() const { return m_changesContinuously; }
Object* object() const { return m_object; }
std::string description() const
{
// TODO
return "StateUpdateEvent(" + lifeCycleToString(m_lifeCycle) + ", " + eventTypeToString(m_eventType) + ")";
}
void setChangesContinuously(bool enable) { m_changesContinuously = enable; }
static std::string lifeCycleToString(LifeCycle lifeCycle)
{
switch(lifeCycle) {
case LifeCycle::Create: return "create";
case LifeCycle::Modify: return "modify";
case LifeCycle::Destroy: return "destroy";
default: return "<no name>";
}
}
//std::string description() const
//{
// // TODO
// return "StateUpdateEvent(" + lifeCycleToString(m_lifeCycle) + ", " + eventTypeToString(m_eventType) + ")";
//}
static std::string eventTypeToString(EventType eventType)
{
switch(eventType) {
case EventType::Explosion: return "explosion";
default: return "<no name>";
}
}
//static std::string lifeCycleToString(LifeCycle lifeCycle)
//{
// switch(lifeCycle) {
// case LifeCycle::Create: return "create";
// case LifeCycle::Modify: return "modify";
// case LifeCycle::Destroy: return "destroy";
// default: return "<no name>";
// }
//}
//static std::string eventTypeToString(EventType eventType)
//{
// switch(eventType) {
// case EventType::Explosion: return "explosion";
// default: return "<no name>";
// }
//}
private:
const LifeCycle m_lifeCycle;
const EventType m_eventType;
Object *m_object;
bool m_changesContinuously;
};
}

View file

@ -57,6 +57,9 @@ namespace util {
{
m_valid = false;
(void) spherePos;
(void) sphereRadius;
// TODO: save if hit.
m_valid = true;
m_rayPos = rayPos;