#include #include #include "Model.h" #include "Physics.h" #include "PhysicsBase.h" #include "EntityFactory.h" #include namespace asteroids { static Model* ModelInstance = NULL; /* * Inherited Module functions */ int Model::OnInit (int argc, char* argv[]) { int result = Engine::ModelBase::OnInit (argc, argv); ModelInstance = this; mGameState = GameStateMainMenu; mLastGameState = GameStateMainMenu; Engine::LogMessage ("Model Initialization!"); return result; } void Model::Process () { if (mLastGameState == mGameState) { if (mGameState == GameStateRunning) { Engine::ModelBase::Process(); } return; } // when we are here we know that something has changed so we need to take // some action. Engine::LogDebug ("Switching from %s->%s", GetStringGameState(mLastGameState), GetStringGameState(mGameState)); if (mLastGameState == GameStateMainMenu && mGameState == GameStateRunning) { mPlayerLives = 3; mLevel = 1; DoLoadLevel ("./data/levels/default.txt"); } else if (mLastGameState == GameStateRunning && mGameState == GameStatePlayerDied) { mPlayerLives --; ClearEntities(); if (mPlayerLives == 0) mGameState = GameStateGameOver; } else if (mLastGameState == GameStateLevelComplete && mGameState == GameStateRunning) DoLoadLevel ("./data/levels/default.txt"); else if (mLastGameState == GameStatePlayerDied && mGameState == GameStateRunning) DoLoadLevel ("./data/levels/default.txt"); else if (mLastGameState == GameStateRunning && mGameState == GameStateGameOver) ClearEntities(); // ... and we have to set the last game state to the current gamestate // otherwise we end up in an infinit loop of performing the switching // action. mLastGameState = mGameState; } int Model::DoLoadLevel (const char* filename) { Engine::LogMessage ("Loading level from %s", filename); std::fstream level_file (filename, std::ios::in); if (!level_file) { Engine::LogError ("Unable to open file %s for writing!", filename); exit (-1); } ClearEntities(); mAsteroids.clear(); std::string entity_type_str; int entity_count = 0; while (level_file >> entity_type_str) { if (entity_type_str[0] == '#') { getline (level_file, entity_type_str); Engine::LogDebug ("Read Comment: %s", entity_type_str.c_str()); continue; } GameEntityType entity_type = GameEntityTypeUnknown; if (entity_type_str == "GameEntityTypeShip") entity_type = GameEntityTypeShip; else if (entity_type_str == "GameEntityTypeAsteroid") entity_type = GameEntityTypeAsteroid; else { Engine::LogError ("Unknown Entity type: %s", entity_type_str.c_str()); exit (-1); } Engine::EntityBase* entity = CreateEntity (entity_type); bool is_player; level_file >> is_player; if (is_player) mPlayerEntityId = entity->mId; level_file >> entity->mPhysicState->mPosition[0]; level_file >> entity->mPhysicState->mPosition[1]; level_file >> entity->mPhysicState->mPosition[2]; level_file >> entity->mPhysicState->mOrientation[0]; level_file >> entity->mPhysicState->mOrientation[1]; level_file >> entity->mPhysicState->mOrientation[2]; level_file >> entity->mPhysicState->mVelocity[0]; level_file >> entity->mPhysicState->mVelocity[1]; level_file >> entity->mPhysicState->mVelocity[2]; level_file >> entity->mPhysicState->mAngleVelocity; entity_count ++; } level_file.close(); Engine::LogDebug ("%d Entities loaded!", mEntities.size()); return 0; } int Model::DoSaveLevel (const char* filename) { Engine::LogMessage ("Saving level to %s", filename); std::fstream level_file (filename, std::ios::out); if (!level_file) { Engine::LogError ("Unable to open file %s for writing!", filename); exit (-1); } level_file << "# Format" << std::endl; level_file << "# " << std::endl; std::map::iterator iter = mEntities.begin(); unsigned int player_id = GetPlayerEntityId(); for (iter = mEntities.begin(); iter != mEntities.end(); iter++) { Engine::EntityBase* game_entity = iter->second; level_file << GetStringGameEntityType((GameEntityType)game_entity->mType) << "\t" // this stores the player id << (game_entity->mId == player_id) << "\t" << game_entity->mPhysicState->mPosition[0] << "\t" << game_entity->mPhysicState->mPosition[1] << "\t" << game_entity->mPhysicState->mPosition[2] << "\t" << game_entity->mPhysicState->mOrientation[0] << "\t" << game_entity->mPhysicState->mOrientation[1] << "\t" << game_entity->mPhysicState->mOrientation[2] << "\t" << game_entity->mPhysicState->mVelocity[0] << "\t" << game_entity->mPhysicState->mVelocity[1] << "\t" << game_entity->mPhysicState->mVelocity[2] << "\t" << game_entity->mPhysicState->mAngleVelocity << "\t" << std::endl; } level_file.close(); return 0; } void Model::OnCreateEntity (const int type, const unsigned int id) { GameEntityType entity_type = (GameEntityType) type; if (entity_type == GameEntityTypeAsteroid) { mAsteroids.push_back (id); } } void Model::OnKillEntity (const Engine::EntityBase *entity) { GameEntityType entity_type = (GameEntityType) entity->mType; if (entity_type == GameEntityTypeAsteroid) { unsigned int i; for (i = 0; i < mAsteroids.size(); i++) { if (mAsteroids.at(i) == entity->mId) { std::vector::iterator entity_iter = mAsteroids.begin() + i; mAsteroids.erase (entity_iter); break; } } if (mAsteroids.size() == 0) { SetGameState (GameStateLevelComplete); } } } float Model::GetWorldWidth () { return static_cast(mPhysics)->GetWorldWidth(); } float Model::GetWorldHeight () { return static_cast(mPhysics)->GetWorldHeight(); } }