diff --git a/asteroids/AsteroidsEnums.h b/asteroids/AsteroidsEnums.h index d490d36..375c403 100644 --- a/asteroids/AsteroidsEnums.h +++ b/asteroids/AsteroidsEnums.h @@ -25,6 +25,7 @@ BEGIN_ENUM(ViewState) DECL_ENUM_ELEMENT(ViewStateGameRunning), DECL_ENUM_ELEMENT(ViewStatePaused), DECL_ENUM_ELEMENT(ViewStatePlayerDied), + DECL_ENUM_ELEMENT(ViewStateShipExplodeFade), DECL_ENUM_ELEMENT(ViewStateLevelComplete), DECL_ENUM_ELEMENT(ViewStateShowHighscore), DECL_ENUM_ELEMENT(ViewStateEnterPlayername), diff --git a/asteroids/Model.cc b/asteroids/Model.cc index 7a7edc0..b81b833 100644 --- a/asteroids/Model.cc +++ b/asteroids/Model.cc @@ -395,27 +395,24 @@ bool Model::OnGameOver() { }; void Model::OnNewGame() { + ClearEntities(); + mNewestHighscoreEntryIndex = 99999; mPlayerLives = 1; mCurrentLevelIndex = 0; mPoints = 0; + DoLoadLevel (mLevelList[mCurrentLevelIndex].c_str()); } void Model::OnShipExplode () { mPlayerLives --; - ClearEntities(); - if (mPlayerLives == 0) { Engine::EventBasePtr gameover_event (new Engine::EventBase()); gameover_event->mEventType = EventGameOver; QueueEvent (gameover_event); - } else { - DoLoadLevel(mLevelList[mCurrentLevelIndex].c_str()); } - - SetGameState(GameStatePaused); } void Model::OnCreateEntity (const int type, const unsigned int id) { diff --git a/asteroids/ShipEntity.cc b/asteroids/ShipEntity.cc index 0163960..3bfa139 100644 --- a/asteroids/ShipEntity.cc +++ b/asteroids/ShipEntity.cc @@ -20,17 +20,6 @@ void ShipEntity::Update (float delta_sec) { if (!mPhysicState || !mControllerState) return; - // If we die, we have to decrease the fade timer - if (!mAlive) { - mFadeTimer -= delta_sec; - - if (mFadeTimer <= 0.) { - Model *model = (Model*) Engine::EngineGetModel(); - model->SetGameState (GameStatePaused); - } - return; - } - mState = Idle; // the local velocity @@ -74,9 +63,6 @@ bool ShipEntity::CollisionEvent (Engine::EntityBase* entity) { Engine::LogMessage ("You died!"); mPhysicState->mStatic = true; - - mAlive = false; - mFadeTimer = 3.; mState = Dying; Engine::EventBasePtr explode_event (new Engine::EventBase()); @@ -89,11 +75,13 @@ bool ShipEntity::CollisionEvent (Engine::EntityBase* entity) { Engine::LogMessage ("You just killed yourself!"); mPhysicState->mStatic = true; - - mAlive = false; - mFadeTimer = 1.; mState = Dying; + Engine::EventBasePtr explode_event (new Engine::EventBase()); + explode_event->mEventType = EventShipExplode; + explode_event->mEventUnsignedInt = mId; + QueueEvent (explode_event); + return true; } diff --git a/asteroids/ShipEntity.h b/asteroids/ShipEntity.h index c00bf31..3b1ad3e 100644 --- a/asteroids/ShipEntity.h +++ b/asteroids/ShipEntity.h @@ -37,8 +37,6 @@ struct ShipEntity: public Engine::EntityBase { mType = GameEntityTypeShip; mBaseType = Engine::EntityBaseTypeActor; - mAlive = true; - mFadeTimer = 0.; mState = Idle; mAttackTimer = 0.; } diff --git a/asteroids/View.cc b/asteroids/View.cc index d7f39bf..3feaea0 100644 --- a/asteroids/View.cc +++ b/asteroids/View.cc @@ -71,6 +71,7 @@ int View::OnInit (int argc, char* argv[]) { Engine::RegisterListener (this, EventAccelerateStart); Engine::RegisterListener (this, EventAccelerateStop); Engine::RegisterListener (this, EventShipExplode); + Engine::RegisterListener (this, EventGameOver); PushViewState (ViewStateMainMenu); @@ -95,33 +96,46 @@ bool View::OnReceiveEvent (const Engine::EventBasePtr &event) { return true; break; - case EventShipExplode: - if (event->mEventType == EventShipExplode) { - Engine::EntityBase *ship_entity = Engine::GetEntity (event->mEventUnsignedInt); - vector3d position = ship_entity->mPhysicState->mPosition; - vector3d orientation = ship_entity->mPhysicState->mOrientation; - vector3d velocity = ship_entity->mPhysicState->mVelocity; - - unsigned int i; - mShipPartsEntityIds.clear(); - - for (i = 0; i < mShipPartsSprite.GetSubSpriteCount(); i++) { - Engine::EntityBase* part_sprite_particle = Engine::CreateEntity (GameEntityTypeShipPart); - part_sprite_particle->mPhysicState->mPosition = position; - part_sprite_particle->mPhysicState->mOrientation = orientation; - part_sprite_particle->mPhysicState->mVelocity = velocity; - part_sprite_particle->mPhysicState->mVelocity = vector3d (velocity[0] * (rand()/float(RAND_MAX)) * 1.7, 0., velocity[2] * (rand()/float(RAND_MAX)) * 1.5); - part_sprite_particle->mPhysicState->mAngleVelocity = (rand()/float(RAND_MAX) - 0.5 ) * 100.; - - mShipPartsEntityIds.push_back(part_sprite_particle->mId); - } - } - - Engine::LogDebug ("Received Ship Explode Event: %d", event->mEventType); - return true; - + case EventGameOver: + PopViewState(); + PushViewState(ViewStateGameOver); + GetModel()->SetGameState(GameStatePaused); break; + case EventShipExplode: { + Engine::LogDebug ("Received Ship Explode Event: %d", event->mEventType); + + PopViewState(); + PushViewState(ViewStatePlayerDied); + GetModel()->SetGameState(GameStatePaused); + + // insert sprits that contains parts of the ship + Engine::EntityBase *ship_entity = Engine::GetEntity (event->mEventUnsignedInt); + vector3d position = ship_entity->mPhysicState->mPosition; + vector3d orientation = ship_entity->mPhysicState->mOrientation; + vector3d velocity = ship_entity->mPhysicState->mVelocity; + + unsigned int i; + mShipPartsEntityIds.clear(); + + for (i = 0; i < mShipPartsSprite.GetSubSpriteCount(); i++) { + Engine::EntityBase* part_sprite_particle = Engine::CreateEntity (GameEntityTypeShipPart); + part_sprite_particle->mPhysicState->mPosition = position; + part_sprite_particle->mPhysicState->mOrientation = orientation; + part_sprite_particle->mPhysicState->mVelocity = velocity; + part_sprite_particle->mPhysicState->mVelocity = vector3d (velocity[0] * (rand()/float(RAND_MAX)) * 1.7, 0., velocity[2] * (rand()/float(RAND_MAX)) * 1.5); + part_sprite_particle->mPhysicState->mAngleVelocity = (rand()/float(RAND_MAX) - 0.5 ) * 100.; + + mShipPartsEntityIds.push_back(part_sprite_particle->mId); + } + + // We do not need the entity anymore + Engine::KillEntity(event->mEventUnsignedInt); + + return true; + + break; + } default: Engine::LogWarning ("Received Event with type %d but don't know what to do with it!", event->mEventType); break; @@ -459,6 +473,7 @@ void View::DrawUiGameRunning() { if (Engine::GUI::CheckKeyPress(SDLK_ESCAPE)) { PushViewState(ViewStatePaused); + GetModel()->SetGameState(GameStatePaused); } } diff --git a/engine/Engine.h b/engine/Engine.h index bb01f52..2e8e72d 100644 --- a/engine/Engine.h +++ b/engine/Engine.h @@ -44,6 +44,7 @@ class Logging; class Commands; class Variables; class Variable; +class Timer; /** \brief The outermost class which contains just everything! * @@ -74,7 +75,7 @@ class Engine : public Module { mSoundManager = NULL; } - virtual void MainLoop () { + void MainLoop () { OnMainLoop (); } diff --git a/engine/ModelBase.cc b/engine/ModelBase.cc index d5ee02c..4368fff 100644 --- a/engine/ModelBase.cc +++ b/engine/ModelBase.cc @@ -49,7 +49,7 @@ void ModelBase::OnDestroy () { */ void ModelBase::Process () { // Process the controllers and state of all entities - std::map::iterator entity_iter = mEntities.begin(); + EntityIter entity_iter = mEntities.begin(); do { if (entity_iter->second == NULL) { LogError ("Entity with id %d does not exist!", entity_iter->first); @@ -58,6 +58,12 @@ void ModelBase::Process () { entity_iter++; } while (entity_iter != mEntities.end()); + // Update the timers + for (TimerIter timer_iter = mTimers.begin(); timer_iter != mTimers.end(); timer_iter++) { + timer_iter->second.Update(mDeltaSec); + timer_iter++; + } + // simulate the world mPhysics->Simulate (mDeltaSec, this); @@ -285,6 +291,23 @@ EntityPhysicState * GetEntityPhysicState (unsigned int id) { return NULL; } +void StartTimer(const std::string &id, float sec) { + if (!ModelInstance) { + LogError ("Couldn't execute GetEntity(): Model not initialized!"); + } + + ModelInstance->StartTimer(id, sec); +} + +bool CheckTimer(const std::string &id) { + if (!ModelInstance) { + LogError ("Couldn't execute GetEntity(): Model not initialized!"); + } + + return ModelInstance->CheckTimer(id); +} + + } diff --git a/engine/ModelBase.h b/engine/ModelBase.h index 538e339..cdfff0b 100644 --- a/engine/ModelBase.h +++ b/engine/ModelBase.h @@ -3,6 +3,7 @@ #include "Engine.h" #include "EntityBase.h" +#include "Timer.h" namespace Engine { @@ -79,6 +80,29 @@ class ModelBase : public Module { }; unsigned int GetGameState () { return mGameState; }; + void StartTimer(const std::string &id, float msec) { + TimerIter cur_timer = mTimers.find(id); + if (cur_timer != mTimers.end()) { + cur_timer->second.Set(msec); + cur_timer->second.Start(); + + return; + } + + mTimers[id] = Timer(id, msec); + assert (mTimers.size() > 0); + assert (mTimers[id].IsActive() == true); + } + bool CheckTimer(const std::string &id) { + TimerIter cur_timer = mTimers.find(id); + + if (cur_timer == mTimers.end()) { + return false; + } + + return cur_timer->second.Query(); + } + protected: /** \brief Initializes the system */ virtual int OnInit (int argc, char* argv[]); @@ -99,9 +123,14 @@ class ModelBase : public Module { /** \brief contains all Engine::Entities */ std::map mEntities; + typedef std::map::iterator EntityIter; + /** \brief contains all Engine::Entities that ceased to exist */ std::vector mKilledEntities; + std::map mTimers; + typedef std::map::iterator TimerIter; + unsigned int mEntityIdCounter; unsigned int mPlayerEntityId; diff --git a/engine/ModelBaseGlobal.h b/engine/ModelBaseGlobal.h index c17ff8b..c4fc78a 100644 --- a/engine/ModelBaseGlobal.h +++ b/engine/ModelBaseGlobal.h @@ -9,6 +9,12 @@ unsigned int GetPlayerEntityId (); /** \brief Returns the duration of the frame in seconds */ float GetFrameDuration (); +/** \brief Starts a timer with the given id that expires after sec seconds */ +void StartTimer(const std::string &id, float sec); + +/** \brief Checks whether a timer expired */ +bool CheckTimer(const std::string &id); + } #endif /* _MODELGLOBAL_H */