213 lines
5.7 KiB
C++
213 lines
5.7 KiB
C++
#include <iostream>
|
|
#include <fstream>
|
|
|
|
#include "Model.h"
|
|
#include "Physics.h"
|
|
#include "PhysicsBase.h"
|
|
|
|
#include "EntityFactory.h"
|
|
|
|
#include <assert.h>
|
|
|
|
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 << "# <Type> <player?> <xpos> <ypos> <zpos> <zrot> <yrot> <xrot> <xvel> <yvel> <zvel> <rotvel>" << std::endl;
|
|
|
|
std::map<unsigned int, Engine::EntityBase*>::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<unsigned int>::iterator entity_iter = mAsteroids.begin() + i;
|
|
mAsteroids.erase (entity_iter);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (mAsteroids.size() == 0) {
|
|
SetGameState (GameStateLevelComplete);
|
|
}
|
|
}
|
|
}
|
|
|
|
float Model::GetWorldWidth () {
|
|
return static_cast<Physics*>(mPhysics)->GetWorldWidth();
|
|
}
|
|
|
|
float Model::GetWorldHeight () {
|
|
return static_cast<Physics*>(mPhysics)->GetWorldHeight();
|
|
}
|
|
|
|
}
|
|
|
|
|