adding event meachinsm for game items that change and sound support.

This commit is contained in:
Andreas Ortmann 2016-10-02 23:49:40 +02:00
parent 9ce106c179
commit f49d07fdc5
15 changed files with 1468 additions and 43 deletions

View file

@ -14,18 +14,16 @@ namespace game {
// angles are supplied in degrees and are CCW
Missile *missile = new Missile(
state->generateMissileId(),
player,
player->ship->position,
-util::deg2rad(m_angle),
0.005*player->speed);
Trace *trace = new Trace(missile);
missile->trace = trace;
player->energy -= player->speed;
player->missiles.push_back(missile);
state->addTrace(trace);
state->addMissile(missile);
}
bool ShootCommand::ready(const Player *player, const State *state) const

View file

@ -0,0 +1,21 @@
#pragma once
#include "state/explosion.hpp"
#include "state/state_update_event.hpp"
namespace game {
class ExplosionEvent : public StateUpdateEvent {
public:
ExplosionEvent(StateUpdateEvent::LifeCycle lifeCycle, Explosion *explosion)
: StateUpdateEvent(lifeCycle, StateUpdateEvent::EventType::Explosion)
, explosion(explosion)
{
std::string typeStr = StateUpdateEvent::lifeCycleToString(lifeCycle);
std::cout<<"created explosion event for id " << explosion->id << " of type " << typeStr << std::endl;
}
public:
Explosion *explosion;
};
}

View file

@ -11,8 +11,9 @@
#include <glm/gtx/norm.hpp>
namespace game {
Missile::Missile(Player *player, const glm::vec2 &pos, float angle, float speed)
: player(player)
Missile::Missile(size_t id, Player *player, const glm::vec2 &pos, float angle, float speed)
: id(id)
, player(player)
, position(pos)
{
velocity = speed * glm::vec2(std::sin(angle), std::cos(angle));

View file

@ -57,17 +57,18 @@ namespace game {
int planetId;
};
Missile(Player *player, const glm::vec2 &pos, float angle, float speed);
Missile(size_t id, Player *player, const glm::vec2 &pos, float angle, float speed);
~Missile();
// try to advance. if something will be hit, return the first hit in
// time.
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;
const size_t id;
Player *player; // owner won't be hit by own missiles
glm::vec2 position;
glm::vec2 velocity;
Trace *trace;
};
}

View file

@ -14,7 +14,7 @@ namespace game {
class Player {
public:
int id;
size_t id;
bool alive;
float speed;
float energy;
@ -23,7 +23,7 @@ namespace game {
std::string name;
std::list<Missile*> missiles;
Player(int id) : id(id), alive(true), speed(1.0), energy(0.0), ship(nullptr), name("<unnamed>")
Player(size_t id) : id(id), alive(true), speed(1.0), energy(0.0), ship(nullptr), name("<unnamed>")
{
}

View file

@ -15,6 +15,9 @@
#include "trace.hpp"
#include "explosion.hpp"
#include "state_update_event.hpp"
#include "events/explosion_event.hpp"
#include "util.hpp"
namespace game {
@ -28,7 +31,8 @@ namespace game {
//for (Player *player : players) {
//}
m_nextId = 0;
m_nextPlayerId = 0;
m_nextMissileId = 0;
m_time = 0.0;
m_shipRadius = 0.02;
m_maxMissileDistance = 2.0;
@ -146,15 +150,15 @@ namespace game {
return true;
}
int State::addPlayer()
size_t State::addPlayer()
{
int playerId = m_nextId++;
size_t playerId = m_nextPlayerId++;
Player *player = new Player(playerId);
players.push_back(player);
return playerId;
}
void State::quitPlayer(int playerId)
void State::quitPlayer(size_t playerId)
{
std::cout << playerId << " quit" << std::endl;
@ -168,12 +172,12 @@ namespace game {
}
}
void State::clear(int playerId)
void State::clear(size_t playerId)
{
std::cout << playerId << " clear" << std::endl;
}
void State::setName(int playerId, std::string name)
void State::setName(size_t playerId, std::string name)
{
// discard if not unique
for (const Player *other : players) {
@ -186,7 +190,7 @@ namespace game {
playerForId(playerId)->name = name;
}
void State::setSpeed(int playerId, double speed)
void State::setSpeed(size_t playerId, double speed)
{
playerForId(playerId)->speed = speed;
}
@ -338,12 +342,15 @@ namespace game {
for (Explosion *explosion : rm) {
explosions.remove(explosion);
delete(explosion);
m_nextEvents.push_back(new ExplosionEvent(StateUpdateEvent::LifeCycle::Destroy, explosion));
//delete(explosion);
}
}
void State::advance(float dt)
{
//std::cout<<"[state] (init) cycle: update events length is " << m_nextEvents.size() << std::endl;
m_time += dt;
advancePlayerShipSpawns(dt);
@ -355,9 +362,19 @@ namespace game {
advancePlayerCommands(dt);
advancePlayerMissiles(dt);
//std::cout<<"[state] (before move) cycle: update events length is " << m_nextEvents.size() << std::endl;
// put collected events into that list.
m_allEvents.push_back(std::move(m_nextEvents));
//std::cout<<"[state] (after move) cycle: update events length is " << m_nextEvents.size() << std::endl;
// finally remove things.
//m_nextEvents.clear();
}
Player *State::playerForId(int playerId)
Player *State::playerForId(size_t playerId)
{
for (Player *p : players) {
if (p->id == playerId) {
@ -402,7 +419,7 @@ namespace game {
}
}
void State::commandForPlayer(int playerId, game::Command *cmd)
void State::commandForPlayer(size_t playerId, game::Command *cmd)
{
Player *player = playerForId(playerId);
if (player != nullptr) {
@ -425,6 +442,14 @@ namespace game {
traces.push_back(trace);
}
void State::addMissile(Missile *missile)
{
Trace *trace = new Trace(missile);
missile->trace = trace;
addTrace(trace);
}
void State::deleteTrace(Trace *trace)
{
if (trace->missile != nullptr) {
@ -442,7 +467,10 @@ namespace game {
return;
}
explosions.push_back(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));
}
void State::advanceTraceAges(float dt)
@ -472,4 +500,23 @@ namespace game {
{
m_playingFieldSize = glm::vec2(width, height);
}
size_t State::generateMissileId()
{
return m_nextMissileId++;
}
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();
}
m_allEvents.clear();
}
}

View file

@ -28,6 +28,7 @@ namespace game {
// forward declarations
class Command;
class Player;
class StateUpdateEvent;
class Ship;
class Trace;
@ -53,15 +54,15 @@ 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);
size_t addPlayer();
void clear(size_t playerId);
void setName(size_t playerId, std::string name);
void setSpeed(size_t playerId, double speed);
void quitPlayer(size_t playerId);
void commandForPlayer(size_t playerId, Command *cmd);
// lookup. return nullptr on invalid playerId
Player *playerForId(int playerId);
Player *playerForId(size_t playerId);
/*************************************************************************/
/* Mixed stuff */
@ -75,6 +76,9 @@ namespace game {
// add a trace to the list of traces.
void addTrace(Trace *trace);
// add a missile
void addMissile(Missile *missile);
// delete traces with this command
void deleteTrace(Trace *trace); // using a pointer
@ -97,10 +101,17 @@ namespace game {
void setPlayingFieldSize(int width, int height);
void setPlayingFieldCenter(int width, int height);
size_t generateMissileId();
void applyAndClearAllOldStateUpdates();
/*************************************************************************/
/* Rendering */
/*************************************************************************/
// TODO: hide and replace by events
// Game items which should be rendered are here:
// (access missiles by iterating over player's missiles attribute)
std::vector<Planet*> planets;
@ -135,17 +146,21 @@ namespace game {
// usefule for spanwing things
bool findFreePositionWithRadius(float r, glm::vec2 &pos);
float m_maxMissileDistance;
float m_playerRespawnTime;
float m_shipRadius;
float m_defaultEnergy;
int m_nextId;
int m_maxNumTraces;
float m_maxMissileDistance;
float m_playerRespawnTime;
float m_shipRadius;
float m_defaultEnergy;
int m_maxNumTraces;
size_t m_nextPlayerId;
size_t m_nextExplosionId;
float m_time;
bool m_developerMode;
size_t m_nextMissileId;
float m_time;
bool m_developerMode;
glm::vec2 m_playingFieldCenter;
glm::vec2 m_playingFieldSize;
std::list<StateUpdateEvent*> m_nextEvents;
std::vector<std::list<StateUpdateEvent*>> m_allEvents;
};
};
}

View file

@ -0,0 +1,51 @@
#pragma once
#include <string>
// 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 {
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)
: m_lifeCycle(cycle), m_eventType(event)
{
}
LifeCycle lifeCycle() const { return m_lifeCycle; }
EventType eventType() const { return m_eventType; }
std::string description() const
{
// TODO
return "<event>";
}
static std::string lifeCycleToString(LifeCycle lifeCycle)
{
switch(lifeCycle) {
case StateUpdateEvent::LifeCycle::Create: return "create";
case StateUpdateEvent::LifeCycle::Modify: return "modify";
case StateUpdateEvent::LifeCycle::Destroy: return "destroy";
default: return "<invalid>";
}
}
private:
const LifeCycle m_lifeCycle;
const EventType m_eventType;
};
}