initial commit

This commit is contained in:
2010-04-05 23:38:59 +02:00
commit e7e0b39e82
150 changed files with 28636 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
#include "Engine.h"
#include "ModelBase.h"
#include "AsteroidEntity.h"
#include "Controller.h"
#include "Model.h"
#include "EntityBase.h"
#include "coll2d.h"
namespace asteroids {
bool AsteroidEntity::CollisionEvent (Engine::EntityBase* entity_state) {
GameEntityType other_type = (GameEntityType) entity_state->mType;
Engine::LogMessage ("CONTACT OF AN ASTEROID");
if (other_type == GameEntityTypeRocket) {
// First remove the rocket
Engine::KillEntity (entity_state->mId);
Engine::LogMessage ("You killed an ASTEROID!");
int i;
for (i = 0; i < mSubAsteroidsCount; i++) {
AsteroidEntity *asteroid = (AsteroidEntity*) Engine::CreateEntity (GameEntityTypeAsteroid);
vector3d position (rand()/float(RAND_MAX) * 1. - 0.5, 0., rand()/float(RAND_MAX) * 1. - 0.5);
asteroid->mSubAsteroidsCount = 0;
asteroid->mPhysicState->mRadius = 2. * mPhysicState->mRadius / mSubAsteroidsCount;
static_cast<coll2d::Sphere*>(asteroid->mPhysicState->mShape)->setRadius (asteroid->mPhysicState->mRadius);
asteroid->mPhysicState->mPosition = mPhysicState->mPosition + position;
asteroid->mPhysicState->mVelocity = position;
asteroid->mPhysicState->mAngleVelocity = mPhysicState->mAngleVelocity + (rand()/float(RAND_MAX) * 2. - 1) * mPhysicState->mAngleVelocity;
}
Engine::KillEntity (mId);
return true;
} else if (other_type == GameEntityTypeRocket) {
return false;
}
return false;
}
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef _ASTEROIDENTITY_H
#define _ASTEROIDENTITY_H
#include "EntityBase.h"
#include "AsteroidsEnums.h"
#include "Sprite.h"
namespace asteroids {
struct AsteroidEntityPhysicState : public Engine::EntityPhysicState {
AsteroidEntityPhysicState () {
mBaseType = Engine::EntityBaseTypeBlock;
mType = GameEntityTypeAsteroid;
}
virtual ~AsteroidEntityPhysicState() {};
};
struct AsteroidEntity: public Engine::EntityBase {
AsteroidEntity () {
mBaseType = Engine::EntityBaseTypeBlock;
mType = GameEntityTypeAsteroid;
mSubAsteroidsCount = 4;
}
virtual bool CollisionEvent (Engine::EntityBase *entity);
int mSubAsteroidsCount;
};
}
#endif // _ASTEROIDENTITY_H
+37
View File
@@ -0,0 +1,37 @@
#if ( !defined(_ASTEROIDSENUMS_H) || defined(GENERATE_ENUM_STRINGS) )
#if ( !defined(GENERATE_ENUM_STRINGS))
#define _ASTEROIDSENUMS_H
#endif
#include "EnumToString.h"
namespace asteroids {
BEGIN_ENUM(GameEntityType)
{
DECL_ENUM_ELEMENT(GameEntityTypeUnknown),
DECL_ENUM_ELEMENT(GameEntityTypeShip),
DECL_ENUM_ELEMENT(GameEntityTypeRocket),
DECL_ENUM_ELEMENT(GameEntityTypeAsteroid),
DECL_ENUM_ELEMENT(GameEntityTypeShipPart),
DECL_ENUM_ELEMENT(GameEntityTypeLast)
}
END_ENUM(GameEntityType)
BEGIN_ENUM(GameState)
{
DECL_ENUM_ELEMENT(GameStateMainMenu),
DECL_ENUM_ELEMENT(GameStateRunning),
DECL_ENUM_ELEMENT(GameStatePaused),
DECL_ENUM_ELEMENT(GameStatePlayerDied),
DECL_ENUM_ELEMENT(GameStateLevelComplete),
DECL_ENUM_ELEMENT(GameStateGameOver)
}
END_ENUM(GameState)
#include "AsteroidsEvents.h"
}
#endif /* _ASTEROIDSENUMS_H */
+14
View File
@@ -0,0 +1,14 @@
#include "EnumToString.h"
namespace asteroids {
BEGIN_ENUM(Event)
{
DECL_ENUM_ELEMENT(EventAccelerateStart),
DECL_ENUM_ELEMENT(EventAccelerateStop),
DECL_ENUM_ELEMENT(EventShipExplode)
}
END_ENUM(Event)
}
+26
View File
@@ -0,0 +1,26 @@
#include "Controller.h"
namespace asteroids {
int Controller::OnInit (int argc, char *argv[]) {
Engine::ControllerBase::OnInit (argc, argv);
mBindings[SDLK_q] = "quit";
mBindings[SDLK_v] = "+forward";
mBindings[SDLK_h] = "+turnleft";
mBindings[SDLK_g] = "+turnright";
mBindings[SDLK_UP] = "+forward";
mBindings[SDLK_LEFT] = "+turnleft";
mBindings[SDLK_RIGHT] = "+turnright";
mBindings[SDLK_SPACE] = "attack";
mBindings[SDLK_F8] = "toggleconsole";
mBindings[SDLK_F9] = "set playerspeed 5.0";
return 0;
}
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef _CONTROLLER_H
#define _CONTROLLER_H
#include "Engine.h"
#include "ControllerBase.h"
namespace asteroids {
/** \brief All possible controller states for an Entity
*
* These are used by the controller to update the current state of an Entity
* (e.g. EntityPhysicState).
*/
enum EntityControllerKeyState {
EntityKeyStateForward = 0,
EntityKeyStateBack,
EntityKeyStateLeft,
EntityKeyStateRight,
EntityKeyStateTurnLeft,
EntityKeyStateTurnRight,
EntityKeyStateLast
};
class Controller : public Engine::ControllerBase {
public:
Controller () {};
protected:
/** \brief Set up basic keybindings */
virtual int OnInit (int argc, char* argv[]);
/** \brief Registers the commands of the cnotroller */
virtual void OnRegisterCommands ();
};
}
#endif // _CONTROLLER_H
+217
View File
@@ -0,0 +1,217 @@
// #include "Engine.h"
#include "Controller.h"
#include "Model.h"
#include "EntityBase.h"
#include "EventsBase.h"
#include "Controller.h"
#include "ShipEntity.h"
#include "AsteroidsEvents.h"
namespace asteroids {
static Controller *ControllerInstance = NULL;
/* +forward */
bool Cmd_ControllerForwardDown (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->SetControllerKeyState (EntityKeyStateForward);
Engine::EventBasePtr forward_event (new Engine::EventBase());
forward_event->mEventType = EventAccelerateStart;
QueueEvent (forward_event);
return true;
}
return false;
}
/* -forward */
bool Cmd_ControllerForwardUp (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->UnsetControllerKeyState (EntityKeyStateForward);
Engine::EventBasePtr forward_event (new Engine::EventBase());
forward_event->mEventType = EventAccelerateStop;
QueueEvent (forward_event);
return true;
}
return false;
}
/* +back */
bool Cmd_ControllerBackDown (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->SetControllerKeyState (EntityKeyStateBack);
return true;
}
return false;
}
/* -back */
bool Cmd_ControllerBackUp (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->UnsetControllerKeyState (EntityKeyStateBack);
return true;
}
return false;
}
/* +left */
bool Cmd_ControllerLeftDown (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->SetControllerKeyState (EntityKeyStateLeft);
return true;
}
return false;
}
/* -left */
bool Cmd_ControllerLeftUp (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->UnsetControllerKeyState (EntityKeyStateLeft);
return true;
}
return false;
}
/* +right */
bool Cmd_ControllerRightDown (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->SetControllerKeyState (EntityKeyStateRight);
return true;
}
return false;
}
/* -right */
bool Cmd_ControllerRightUp (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->UnsetControllerKeyState (EntityKeyStateRight);
return true;
}
return false;
}
/* +turnleft */
bool Cmd_ControllerTurnLeftDown (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->SetControllerKeyState (EntityKeyStateTurnLeft);
return true;
}
return false;
}
/* -turnleft */
bool Cmd_ControllerTurnLeftUp (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->UnsetControllerKeyState (EntityKeyStateTurnLeft);
return true;
}
return false;
}
/* +turnright */
bool Cmd_ControllerTurnRightDown (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->SetControllerKeyState (EntityKeyStateTurnRight);
return true;
}
return false;
}
/* -turnright */
bool Cmd_ControllerTurnRightUp (std::vector<std::string> args) {
assert (ControllerInstance);
Engine::EntityBase* player_entity = Engine::GetEntity (Engine::GetPlayerEntityId());
if (player_entity) {
player_entity->UnsetControllerKeyState (EntityKeyStateTurnRight);
return true;
}
return false;
}
/* attack */
bool Cmd_ControllerAttack (std::vector<std::string> args) {
assert (ControllerInstance);
ShipEntity* player_entity = (ShipEntity*) Engine::GetEntity (Engine::GetPlayerEntityId ());
assert (player_entity);
player_entity->Attack ();
return true;
}
void Controller::OnRegisterCommands () {
ControllerBase::OnRegisterCommands ();
ControllerInstance = this;
Engine::AddCommand ("+forward", Cmd_ControllerForwardDown);
Engine::AddCommand ("-forward", Cmd_ControllerForwardUp);
Engine::AddCommand ("+back", Cmd_ControllerBackDown);
Engine::AddCommand ("-back", Cmd_ControllerBackUp);
Engine::AddCommand ("+left", Cmd_ControllerLeftDown);
Engine::AddCommand ("-left", Cmd_ControllerLeftUp);
Engine::AddCommand ("+right", Cmd_ControllerRightDown);
Engine::AddCommand ("-right", Cmd_ControllerRightUp);
Engine::AddCommand ("+turnleft", Cmd_ControllerTurnLeftDown);
Engine::AddCommand ("-turnleft", Cmd_ControllerTurnLeftUp);
Engine::AddCommand ("+turnright", Cmd_ControllerTurnRightDown);
Engine::AddCommand ("-turnright", Cmd_ControllerTurnRightUp);
Engine::AddCommand ("attack", Cmd_ControllerAttack);
}
}
+139
View File
@@ -0,0 +1,139 @@
#include <iostream>
#include "EntityBase.h"
#include "coll2d.h"
#include "EntityFactory.h"
#include "ShipEntity.h"
#include "RocketEntity.h"
#include "AsteroidEntity.h"
namespace asteroids {
int EntityFactory::OnInit (int argc, char* argv[]) {
Engine::LogMessage ("Initializing EntityFactory");
return 0;
}
Engine::EntityPhysicState* EntityFactory::CreateEntityPhysicState (int type) {
// In this simple factory the type is simply seen as the EntityBaseType.
// However to prevent errors we do a simple check vor validity.
if (type < 0 || type > GameEntityTypeLast ) {
Engine::LogError ("Cannot create Entity with type %d: invalid type!", type);
assert (0);
}
// Create the Entity
Engine::EntityPhysicState* entity_physics = NULL;
// type specific initialization
if (type == GameEntityTypeShip) {
entity_physics = new ShipEntityPhysicState ();
if (!entity_physics) {
Engine::LogError ("Could not allocate enough memory for EntityPhysicState of type '%d'", type);
assert (0);
}
entity_physics->mRadius = 0.5;
entity_physics->mShape = new coll2d::Sphere (entity_physics->mRadius);
assert (entity_physics->mShape);
} else if (type == GameEntityTypeAsteroid) {
entity_physics = new AsteroidEntityPhysicState ();
if (!entity_physics) {
Engine::LogError ("Could not allocate enough memory for EntityPhysicState of type '%d'", type);
assert (0);
}
entity_physics->mRadius = 1.;
entity_physics->mShape = new coll2d::Sphere (entity_physics->mRadius);
assert (entity_physics->mShape);
} else if (type == GameEntityTypeRocket) {
entity_physics = new RocketEntityPhysicState();
if (!entity_physics) {
Engine::LogError ("Could not allocate enough memory for EntityPhysicState of type '%d'", type);
assert (0);
}
entity_physics->mRadius = 0.1;
entity_physics->mShape = new coll2d::Sphere (entity_physics->mRadius);
} else if (type == GameEntityTypeShipPart) {
entity_physics = new RocketEntityPhysicState();
entity_physics->mBaseType = Engine::EntityBaseTypeBlock;
if (!entity_physics) {
Engine::LogError ("Could not allocate enough memory for EntityPhysicState of type '%d'", type);
assert (0);
}
entity_physics->mRadius = 0.1;
entity_physics->mShape = new coll2d::Sphere (entity_physics->mRadius);
} else {
Engine::LogError ("No EntityPhysicState defined for GameEntity type '%d'", type);
assert (0);
}
entity_physics->mType = type;
return entity_physics;
}
Engine::EntityControllerState* EntityFactory::CreateEntityControllerState (int type) {
// In this simple factory the type is simply seen as the EntityBaseType.
// However to prevent errors we do a simple check vor validity.
if (type < 0 || type >> Engine::EntityBaseTypeLast ) {
Engine::LogError ("Cannot create Entity with type %d: invalid type!", type);
assert (0);
}
// Create the Entity
Engine::EntityControllerState* entity_controller = NULL;
// specific values for each type
if (type == GameEntityTypeShip) {
entity_controller = new Engine::EntityControllerState ();
if (!entity_controller) {
Engine::LogError ("Could not allocate enough memory for EntityControllerState of type '%d'", type);
assert (0);
}
}
return entity_controller;
}
Engine::EntityBase* EntityFactory::CreateEntity (int type) {
// In this simple factory the type is simply seen as the EntityBaseType.
// However to prevent errors we do a simple check vor validity.
if (type < 0 || type > GameEntityTypeLast ) {
Engine::LogError ("Cannot create Entity with type %d: invalid type!", type);
assert (0);
}
// Create the Entity
Engine::EntityBase *entity;
if (type == GameEntityTypeShip) {
entity = new ShipEntity;
} else if (type == GameEntityTypeAsteroid) {
entity = new AsteroidEntity;
} else if (type == GameEntityTypeRocket) {
entity = new RocketEntity;
} else if (type == GameEntityTypeShipPart) {
entity = new Engine::EntityBase;
entity->mBaseType = Engine::EntityBaseTypeBlock;
}
entity->mType = type;
if (!entity) {
Engine::LogError ("Could not allocate enough memory for EntityVisualState of type '%d'", type);
assert (0);
}
entity->mPhysicState = CreateEntityPhysicState (type);
entity->mControllerState = CreateEntityControllerState (type);
return entity;
}
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef _ENTITYFACTORY_H
#define _ENTITYFACTORY_H
#include "EntityFactoryBase.h"
#include "AsteroidsEnums.h"
namespace Engine {
struct EntityBase;
struct EntityPhysicState;
struct EntityControllerState;
}
namespace asteroids {
class EntityFactory: public Engine::EntityFactoryBase {
public:
EntityFactory () {};
virtual Engine::EntityPhysicState* CreateEntityPhysicState (int type);
virtual Engine::EntityControllerState* CreateEntityControllerState (int type);
virtual Engine::EntityBase* CreateEntity (int type);
protected:
virtual int OnInit (int argc, char *argv[]);
};
}
#endif // _ENTITYFACTORY_H
+7
View File
@@ -0,0 +1,7 @@
#include "AsteroidsEnums.h"
#define GENERATE_ENUM_STRINGS
#include "AsteroidsEnums.h"
#undef GENERATE_ENUM_STRINGS
+176
View File
@@ -0,0 +1,176 @@
#include "OGLFT.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include "DrawingsGL.h"
#include "OverlayBase.h"
#include "MenuOverlay.h"
#include "Model.h"
#include "Sprite.h"
#include "ShipEntity.h"
#include "Engine.h"
namespace asteroids {
// static float left = 0;
static float right = 0;
// static float top = 0;
static float bottom = 0;
void MenuOverlay::Init () {
if (!mShipSprite.LoadFromPNG("./data/textures/ship.png"))
Engine::LogError ("Could not load ship sprite!");
assert (mShipSprite.GetWidth() > 1);
mShipSprite.SetScale (0.1);
}
bool MenuOverlay::OnKeyDown (const SDL_keysym &keysym) {
if (mModel->GetGameState() == GameStateLevelComplete) {
switch (keysym.sym) {
case SDLK_RETURN:
mModel->SetGameState(GameStateRunning);
break;
default:
break;
}
return true;
} else if (mModel->GetGameState() == GameStateRunning) {
switch (keysym.sym) {
case SDLK_ESCAPE:
mModel->SetGameState(GameStatePaused);
return true;
default:
break;
}
return false;
} else if (mModel->GetGameState() == GameStateGameOver) {
switch (keysym.sym) {
case SDLK_ESCAPE:
mModel->SetGameState(GameStateMainMenu);
break;
case SDLK_RETURN:
mModel->SetGameState(GameStateMainMenu);
break;
default:
break;
}
return true;
}
else if (mModel->GetGameState() == GameStateMainMenu
|| mModel->GetGameState() == GameStatePaused) {
switch (keysym.sym) {
case SDLK_ESCAPE:
Engine::RunCommand ("quit");
return true;
case SDLK_RETURN:
mModel->SetGameState(GameStateRunning);
return true;
default:
return true;
}
} else if (mModel->GetGameState() == GameStatePlayerDied) {
switch (keysym.sym) {
case SDLK_RETURN:
mModel->SetGameState(GameStateRunning);
break;
default:
break;
}
return true;
}
return false;
}
void MenuOverlay::Draw () {
glClearColor (0.1, 0.1, 0.1, 1.);
right = static_cast<float> (Engine::GetWindowWidth());
bottom = static_cast<float> (Engine::GetWindowHeight());
// we switch to orthographic projection and draw the contents of the 2d
// overlay on top of the previous drawings
glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();
// first we have to get the size of the current viewport to set up the
// orthographic projection correctly
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
gluOrtho2D (viewport[0], viewport[2], viewport[3], viewport[1]);
glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
glLoadIdentity ();
// then we do the drawings
if (mModel->GetGameState() == GameStateRunning) {
glClearColor (0., 0., 0., 1.);
DrawGameRunning();
} else if (mModel->GetGameState() == GameStateGameOver)
DrawGameOverScreen ();
else if (mModel->GetGameState() == GameStateMainMenu
|| mModel->GetGameState() == GameStatePaused)
DrawGameMenu ();
else if (mModel->GetGameState() == GameStateLevelComplete)
DrawGameLevelComplete ();
else if (mModel->GetGameState() == GameStatePlayerDied)
DrawPlayerDied();
glPopMatrix ();
glMatrixMode (GL_PROJECTION);
glPopMatrix ();
glMatrixMode (GL_MODELVIEW);
};
void MenuOverlay::DrawGameRunning() {
right = static_cast<float> (Engine::GetWindowWidth());
bottom = static_cast<float> (Engine::GetWindowHeight());
int i;
for (i = 0; i < mModel->GetPlayerLives(); i++) {
mShipSprite.DrawAt2D (right - 32 - i*20, bottom - 16);
}
}
void MenuOverlay::DrawPlayerDied () {
std::ostringstream topbar_stream;
topbar_stream << "You died ...";
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 - 8, topbar_stream.str().c_str ());
}
void MenuOverlay::DrawGameOverScreen() {
std::ostringstream topbar_stream;
topbar_stream << "That was pathetic! ";
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 - 8, topbar_stream.str().c_str ());
}
void MenuOverlay::DrawGameMenu() {
Engine::DrawGLString ( right * 0.5 - 100, bottom * 0.5 - 8 - 64, "A s t e r o i d s");
Engine::DrawGLString ( right * 0.5 - 100, bottom * 0.5 - 8 - 32, "Main Menu");
if (mModel->GetGameState() == GameStatePaused)
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 - 8 - 16, "[Return] - Resume Game");
else
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 - 8 - 16, "[Return] - Start Game");
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 - 8, "[Escape] - Quit");
}
void MenuOverlay::DrawGameLevelComplete() {
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 - 8 - 16, "Congratulations - You rock!");
Engine::DrawGLString ( right * 0.5 - 80, bottom * 0.5 - 8, "[Return] - Next level ...");
}
}
+41
View File
@@ -0,0 +1,41 @@
#ifndef MENUOVERLAY
#define MENUOVERLAY
namespace Engine {
class OverlayBase;
}
#include "OverlayBase.h"
#include "Sprite.h"
namespace asteroids {
class Model;
class MenuOverlay : public Engine::OverlayBase {
public:
MenuOverlay () {
};
void Init ();
virtual ~MenuOverlay() {};
virtual bool OnKeyDown (const SDL_keysym &keysym);
virtual void Draw ();
void DrawGameOverScreen ();
void DrawGameMenu();
void DrawGameLevelComplete ();
void DrawGamePaused ();
void DrawGameRunning ();
void DrawPlayerDied ();
void SetModel (Model *model) { mModel = model; };
private:
Model *mModel;
Engine::Sprite mShipSprite;
};
}
#endif /* MENUOVERLAY */
+213
View File
@@ -0,0 +1,213 @@
#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] == '#') {
std::cout << "Read Comment: " << entity_type_str;
getline (level_file, entity_type_str);
std::cout << entity_type_str << std::endl;
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();
}
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef _MODEL_H
#define _MODEL_H
#include "ModelBase.h"
#include "AsteroidsEnums.h"
namespace asteroids {
class Model : public Engine::ModelBase {
public:
virtual void Process();
int DoLoadLevel (const char* filename);
int DoSaveLevel (const char* filename);
void SetGameState (const GameState &state) {
mLastGameState = mGameState;
mGameState = state;
};
GameState GetGameState () { return mGameState; };
int GetPlayerLives () { return mPlayerLives; };
float GetWorldWidth ();
float GetWorldHeight ();
protected:
/** \brief Initializes the system */
virtual int OnInit (int argc, char* argv[]);
virtual void OnRegisterCommands ();
virtual void OnCreateEntity (const int type, const unsigned int id);
virtual void OnKillEntity (const Engine::EntityBase *entity);
private:
/** \brief Keeps a list of all asteroids */
std::vector<unsigned int> mAsteroids;
GameState mGameState;
GameState mLastGameState;
int mPlayerLives;
int mLevel;
friend class View;
};
}
#endif // _MODEL_H
+48
View File
@@ -0,0 +1,48 @@
#include "Model.h"
namespace asteroids {
static Model *ModelInstance = NULL;
bool Cmd_SaveLevel (const std::vector<std::string> args) {
assert (ModelInstance);
if (args.size() != 1) {
Engine::CommandSetErrorString ("usage: savelevel <path_to_level>");
return false;
}
if (ModelInstance->DoSaveLevel (args[0].c_str()) > 0)
return true;
// ToDo: Maybe some error output?
return false;
}
bool Cmd_LoadLevel (const std::vector<std::string> args) {
assert (ModelInstance);
if (args.size() != 1) {
Engine::CommandSetErrorString ("usage: loadlevel <path_to_level>");
return false;
}
if (ModelInstance->DoLoadLevel (args[0].c_str()) > 0)
return true;
// ToDo: Maybe some error output?
return false;
}
void Model::OnRegisterCommands () {
ModelInstance = this;
Engine::ModelBase::OnRegisterCommands ();
Engine::AddCommand ("savelevel", Cmd_SaveLevel);
Engine::AddCommand ("loadlevel", Cmd_LoadLevel);
}
}
+58
View File
@@ -0,0 +1,58 @@
#include <iostream>
#include <fstream>
#include "Model.h"
#include "Physics.h"
#include "EntityFactory.h"
#include <assert.h>
namespace asteroids {
static Physics* PhysicsInstance = NULL;
/*
* Inherited Module functions
*/
int Physics::OnInit (int argc, char* argv[]) {
Engine::PhysicsBase::OnInit (argc, argv);
Engine::LogMessage ("Physics Initialization!");
PhysicsInstance = this;
mWorldWidth = 16;
mWorldHeight = 16;
return 0;
}
int Physics::Simulate (float msec, Engine::ModelBase *model) {
int result = Engine::PhysicsBase::Simulate (msec, model);
Engine::EntityPhysicState* entity = NULL;
std::map<unsigned int, Engine::EntityPhysicState*>::iterator entity_iter;
for (entity_iter = mEntities.begin ();
entity_iter != mEntities.end();
entity_iter++) {
entity = entity_iter->second;
if (entity->mPosition[0] > mWorldWidth * 0.5)
entity->mPosition[0] -= mWorldWidth;
if (entity->mPosition[0] < - mWorldWidth * 0.5)
entity->mPosition[0] += mWorldWidth;
if (entity->mPosition[2] > mWorldHeight * 0.5)
entity->mPosition[2] -= mWorldHeight;
if (entity->mPosition[2] < - mWorldHeight * 0.5)
entity->mPosition[2] += mWorldHeight;
}
return result;
}
}
+34
View File
@@ -0,0 +1,34 @@
#ifndef _PHYSICS_H
#define _PHYSICS_H
#include "PhysicsBase.h"
namespace Engine {
class Model;
}
namespace asteroids {
class Physics : public Engine::PhysicsBase {
public:
virtual int Simulate (float msec, Engine::ModelBase* model = NULL);
void SetWorldSize (float width, float height) {
mWorldWidth = width;
mWorldHeight = height;
}
float GetWorldWidth () { return mWorldWidth; }
float GetWorldHeight () { return mWorldHeight; }
protected:
virtual int OnInit (int argc, char* argv[]);
private:
float mWorldWidth;
float mWorldHeight;
};
}
#endif // _PHYSICS_H
+17
View File
@@ -0,0 +1,17 @@
#include "Model.h"
#include "RocketEntity.h"
#include "Controller.h"
#include <GL/gl.h>
namespace asteroids {
void RocketEntity::Update (float delta_sec) {
mSecToLive -= delta_sec;
if (mSecToLive <= 0.)
Engine::KillEntity (mId);
}
}
+39
View File
@@ -0,0 +1,39 @@
#ifndef _ROCKETENTITY_H
#define _ROCKETENTITY_H
#include "EntityBase.h"
#include "AsteroidsEnums.h"
#include "Sprite.h"
namespace asteroids {
struct RocketEntityPhysicState : public Engine::EntityPhysicState {
RocketEntityPhysicState () {
mBaseType = Engine::EntityBaseTypeParticle;
mType = GameEntityTypeRocket;
}
virtual ~RocketEntityPhysicState() {};
};
struct RocketEntity: public Engine::EntityBase {
RocketEntity () {
mBaseType = Engine::EntityBaseTypeParticle;
mType = GameEntityTypeRocket;
mSecToLive = 3.;
}
virtual ~RocketEntity() {};
virtual void Update (float delta_sec);
virtual bool CollisionEvent (Engine::EntityBase *entity) {
Engine::LogMessage ("Rocket BOOM");
return false;
}
float mSecToLive;
};
}
#endif // _ROCKETENTITY_H
+122
View File
@@ -0,0 +1,122 @@
#include "Engine.h"
#include "Model.h"
#include "ShipEntity.h"
#include "RocketEntity.h"
#include "Controller.h"
#include "AsteroidsEvents.h"
#include "coll2d.h"
namespace asteroids {
static Engine::Variable var_ship_acceleration ("ship_acceleration", "10");
static Engine::Variable var_ship_maxspeed ("ship_maxspeed", "10");
static Engine::Variable var_ship_rotationspeed ("ship_rotationspeed", "180");
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 (GameStatePlayerDied);
}
return;
}
mState = Idle;
// the local velocity
vector3d local_velocity = mPhysicState->mVelocity;
mPhysicState->LocalizeRotation (local_velocity);
// set the local velocity as the current state of the keys are
if (mControllerState->GetKey (EntityKeyStateForward)) {
local_velocity[0] += delta_sec * var_ship_acceleration.GetFloatValue();
mState = Accelerating;
}
// now transform these to global velocities
mPhysicState->GlobalizeRotation (local_velocity);
// now we can update the new global velocity
mPhysicState->SetVelocity(local_velocity);
if (mControllerState->GetKey (EntityKeyStateTurnLeft)) {
mPhysicState->mOrientation[1] += delta_sec * var_ship_rotationspeed.GetFloatValue();
}
if (mControllerState->GetKey (EntityKeyStateTurnRight)) {
mPhysicState->mOrientation[1] -= delta_sec * var_ship_rotationspeed.GetFloatValue();
}
// Check for the maximum speed
float speed = mPhysicState->mVelocity.length();
if (speed > var_ship_maxspeed.GetFloatValue()) {
mPhysicState->mVelocity *= var_ship_maxspeed.GetFloatValue() / speed;
}
}
bool ShipEntity::CollisionEvent (Engine::EntityBase* entity) {
GameEntityType other_type = (GameEntityType) entity->mType;
if (other_type == GameEntityTypeAsteroid) {
Engine::LogMessage ("You died!");
mPhysicState->mStatic = true;
mAlive = false;
mFadeTimer = 3.;
mState = Dying;
Engine::EventBasePtr explode_event (new Engine::EventBase());
explode_event->mEventType = EventShipExplode;
explode_event->mEventUnsignedInt = mId;
QueueEvent (explode_event);
return true;
} else if (other_type == GameEntityTypeRocket) {
Engine::LogMessage ("You just killed yourself!");
mPhysicState->mStatic = true;
mAlive = false;
mFadeTimer = 1.;
mState = Dying;
return true;
}
return false;
}
void ShipEntity::Attack () {
if (!mAlive)
return;
Engine::LogMessage ("ATTACK");
Engine::EntityPhysicState* entity_physic = Engine::GetEntityPhysicState (mId);
vector3d attack_dir (1., 0., 0.);
entity_physic->GlobalizeRotation (attack_dir);
RocketEntity *rocket_entity = (RocketEntity*) Engine::CreateEntity (GameEntityTypeRocket);
rocket_entity->mSecToLive = 1.75;
RocketEntityPhysicState *rocket_physics = (RocketEntityPhysicState*) rocket_entity->mPhysicState;
rocket_physics->mPosition = attack_dir;
rocket_physics->mPosition *= mPhysicState->mRadius;
rocket_physics->mPosition += entity_physic->mPosition;
rocket_physics->mOrientation = entity_physic->mOrientation;
rocket_physics->mVelocity = attack_dir.normalize();
rocket_physics->mVelocity *= var_ship_maxspeed.GetFloatValue() + 0.1;
}
}
+58
View File
@@ -0,0 +1,58 @@
#ifndef _SHIPENTITY_H
#define _SHIPENTITY_H
#include "EntityBase.h"
#include "AsteroidsEnums.h"
#include "Sprite.h"
namespace asteroids {
struct ShipEntityPhysicState : public Engine::EntityPhysicState {
ShipEntityPhysicState () {
mType = GameEntityTypeShip;
mBaseType = Engine::EntityBaseTypeActor;
mAcceleration = 10.;
mMaxSpeed = 10.;
mRotationSpeed = 180.;
}
virtual ~ShipEntityPhysicState() {};
float mAcceleration;
float mMaxSpeed;
float mRotationSpeed;
};
struct ShipEntity: public Engine::EntityBase {
enum State {
Idle = 0,
Accelerating,
Rotating,
Shooting,
Dying
};
ShipEntity () {
mType = GameEntityTypeShip;
mBaseType = Engine::EntityBaseTypeActor;
mAlive = true;
mFadeTimer = 0.;
mState = Idle;
}
virtual ~ShipEntity() {};
virtual void Attack ();
virtual void Update (float delta_sec);
virtual bool CollisionEvent (Engine::EntityBase *entity);
bool mAlive;
float mFadeTimer;
State mState;
};
}
#endif // _SHIPENTITY_H
+359
View File
@@ -0,0 +1,359 @@
#include "View.h"
#include "CameraBase.h"
#include "MenuOverlay.h"
#include "SimpleConsoleOverlay.h"
#include "Engine.h"
#include "Physics.h"
#include "Model.h"
#include "EventsBase.h"
#include "ShipEntity.h"
#include "AsteroidEntity.h"
#include "AsteroidsEvents.h"
#include "RocketEntity.h"
#include <GL/gl.h>
// #define DRAW_BOUNDARIES
#ifdef DRAW_BOUNDARIES
#include "coll2d.h"
#include "DrawingsGL.h"
#endif
using namespace std;
namespace asteroids {
int View::OnInit (int argc, char* argv[]) {
ViewBase::OnInit (argc, argv);
// We want menu
mMenuOverlay = new MenuOverlay;
mMenuOverlay->SetModel ((Model*) mModel);
mMenuOverlay->Init();
AddOverlay (mMenuOverlay);
// We want the console
Engine::SimpleConsoleOverlay *console = new Engine::SimpleConsoleOverlay;
// We also want to display the log bar
console->SetDrawLogBar (true);
AddOverlay (console);
// This is a simple star field that makes the game so spacy
int i;
for (i = 0; i < 200; i++) {
BackgroundStar star;
star.position[0] = rand() / float(RAND_MAX);
star.position[1] = rand() / float(RAND_MAX);
star.position[2] = rand() / float(RAND_MAX);
mBackgroundStars.push_back (star);
}
mAsteroidSprite.LoadFromPNG ("./data/textures/asteroid.png");
mShipSprite.LoadFromPNG ("./data/textures/ship.png");
mShipThrustSprite.LoadFromPNG ("./data/textures/ship_thrust.png");
mShipThrustSprite.SetAnimation (4, 8);
mShipPartsSprite.LoadFromPNG ("./data/textures/ship_parts.png");
mShipPartsSprite.SetSubSpriteCount (10);
mAccelerateEventHandler = new AccelerateEventHandler (this);
Engine::RegisterListener (mAccelerateEventHandler, EventAccelerateStart);
Engine::RegisterListener (mAccelerateEventHandler, EventAccelerateStop);
mShipExplodeEventHandler = new ShipExplodeEventHandler (this);
Engine::RegisterListener (mShipExplodeEventHandler, EventShipExplode);
return 0;
}
void View::OnDestroy() {
delete mAccelerateEventHandler;
}
/*
* Event Handlers
*/
bool View::AccelerateEventHandler::HandleEvent (const Engine::EventBasePtr &event) const {
if (event->mEventType == EventAccelerateStart)
mView->mShipThrustSprite.ResetAnimation();
Engine::LogMessage ("Received Acceleration Event: %d", event->mEventType);
return true;
}
bool View::ShipExplodeEventHandler::HandleEvent (const Engine::EventBasePtr &event) const {
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;
mView->mShipPartsEntityIds.clear();
for (i = 0; i < mView->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.;
mView->mShipPartsEntityIds.push_back(part_sprite_particle->mId);
}
}
Engine::LogMessage ("Received Ship Explode Event: %d", event->mEventType);
return true;
}
/*
* Module specific functions
*/
void View::UpdateCamera () {
mCamera->SetEye (
0.,
9.5,
0.
);
mCamera->SetPointOfIntrest (
0.,
0.,
0.
);
mCamera->SetUp (
0.,
0.,
-1.
);
mCamera->Update ();
}
void View::DrawStars() {
unsigned int i;
float world_width, world_height;
world_width = static_cast<Model*>(mModel)->GetWorldWidth();
world_height = static_cast<Model*>(mModel)->GetWorldHeight();
vector3d velocity (1., 0., 0.);
glPushMatrix();
glTranslatef(-world_width * 0.5, 0, -world_height * 0.5);
glColor3f (1., 1., 1.);
glPointSize(2.);
glBegin(GL_POINTS);
float z_value;
for (i = 0; i < mBackgroundStars.size(); i++) {
// glPointSize (2. + 300. *mBackgroundStars.at(i).position[1]);
z_value = mBackgroundStars.at(i).position[1] + 0.1;
glColor3f (z_value, z_value, z_value);
glVertex3f (mBackgroundStars.at(i).position[0] * world_width,
-1.,
mBackgroundStars.at(i).position[2] * world_height);
mBackgroundStars.at(i).position -= vector3d(Engine::GetFrameDuration() * 0.7 * mBackgroundStars.at(i).position[1] / world_width, 0., 0.);
if (mBackgroundStars.at(i).position[0] < 0.)
mBackgroundStars.at(i).position[0] += 1.;
if (mBackgroundStars.at(i).position[0] >= 1.)
mBackgroundStars.at(i).position[0] -= 1.;
}
glEnd();
glPopMatrix();
}
void View::DrawWorld() {
std::map<unsigned int, Engine::EntityBase*>::iterator entity_iterator;
Model *game_model = static_cast<Model*> (mModel);
DrawStars ();
if ( game_model->GetGameState() != GameStateRunning) {
return;
}
ViewBase::DrawWorld();
for (entity_iterator = game_model->mEntities.begin ();
entity_iterator != game_model->mEntities.end();
entity_iterator++) {
Engine::EntityBase* entity = entity_iterator->second;
// Perform multiple drawing if the entity is at the border
Physics* game_physics = (Physics*) game_model->mPhysics;
float world_width = game_physics->GetWorldWidth();
float world_height = game_physics->GetWorldHeight();
// Drawing at the original position:
glPushMatrix ();
glTranslatef (entity->mPhysicState->mPosition[0],
entity->mPhysicState->mPosition[1],
entity->mPhysicState->mPosition[2]);
glRotatef(entity->mPhysicState->mOrientation[0], 0., 0., 1.);
glRotatef(entity->mPhysicState->mOrientation[1], 0., 1., 0.);
glRotatef(entity->mPhysicState->mOrientation[2], 1., 0., 0.);
glColor3f (1., 1., 1.);
DrawEntity (entity);
glPopMatrix ();
// If we move out the right side
if (entity->mPhysicState->mPosition[0] + entity->mPhysicState->mRadius * 2
>= world_width * 0.5) {
glPushMatrix ();
glTranslatef (entity->mPhysicState->mPosition[0] - world_width,
entity->mPhysicState->mPosition[1],
entity->mPhysicState->mPosition[2]);
glRotatef(entity->mPhysicState->mOrientation[0], 0., 0., 1.);
glRotatef(entity->mPhysicState->mOrientation[1], 0., 1., 0.);
glRotatef(entity->mPhysicState->mOrientation[2], 1., 0., 0.);
glColor3f (1., 1., 1.);
DrawEntity (entity);
glPopMatrix ();
}
// if we move out the left side
if (entity->mPhysicState->mPosition[0] - entity->mPhysicState->mRadius * 2
< - world_width * 0.5) {
glPushMatrix ();
glTranslatef (entity->mPhysicState->mPosition[0] + world_width,
entity->mPhysicState->mPosition[1],
entity->mPhysicState->mPosition[2]);
glRotatef(entity->mPhysicState->mOrientation[0], 0., 0., 1.);
glRotatef(entity->mPhysicState->mOrientation[1], 0., 1., 0.);
glRotatef(entity->mPhysicState->mOrientation[2], 1., 0., 0.);
glColor3f (1., 1., 1.);
DrawEntity (entity);
glPopMatrix ();
}
// If we move out the bottom side
if (entity->mPhysicState->mPosition[2] + entity->mPhysicState->mRadius * 2
>= world_height * 0.5) {
glPushMatrix ();
glTranslatef (entity->mPhysicState->mPosition[0],
entity->mPhysicState->mPosition[1],
entity->mPhysicState->mPosition[2] - world_height);
glRotatef(entity->mPhysicState->mOrientation[0], 0., 0., 1.);
glRotatef(entity->mPhysicState->mOrientation[1], 0., 1., 0.);
glRotatef(entity->mPhysicState->mOrientation[2], 1., 0., 0.);
glColor3f (1., 1., 1.);
DrawEntity (entity);
glPopMatrix ();
}
// if we move out the left side
if (entity->mPhysicState->mPosition[2] - entity->mPhysicState->mRadius * 2
< - world_height* 0.5) {
glPushMatrix ();
glTranslatef (entity->mPhysicState->mPosition[0],
entity->mPhysicState->mPosition[1],
entity->mPhysicState->mPosition[2] + world_height);
glRotatef(entity->mPhysicState->mOrientation[0], 0., 0., 1.);
glRotatef(entity->mPhysicState->mOrientation[1], 0., 1., 0.);
glRotatef(entity->mPhysicState->mOrientation[2], 1., 0., 0.);
glColor3f (1., 1., 1.);
DrawEntity (entity);
glPopMatrix ();
}
}
}
void View::DrawEntity (Engine::EntityBase *entity) {
if (entity->mType == GameEntityTypeAsteroid)
DrawAsteroid ((AsteroidEntity*) entity);
else if (entity->mType == GameEntityTypeShip)
DrawShip ((ShipEntity*) entity);
else if (entity->mType == GameEntityTypeRocket)
DrawRocket ((RocketEntity*) entity);
else if (entity->mType == GameEntityTypeShipPart)
DrawShipPart (entity);
else {
Engine::LogError ("Cannot draw entity: unknown type '%d'", entity->mType);
}
}
/// \todo: Update of the animation ??
void View::DrawShip (ShipEntity *ship) {
if (!ship->mAlive)
return;
mShipSprite.SetScale (2. * ship->mPhysicState->mRadius / mShipSprite.GetHeight());
mShipThrustSprite.SetScale (2. * ship->mPhysicState->mRadius / mShipSprite.GetHeight());
if (ship->mState == ShipEntity::Accelerating) {
mShipThrustSprite.UpdateAnimation (Engine::GetFrameDuration());
mShipThrustSprite.DrawAt(-0.5, 0., 0.);
}
mShipSprite.DrawAt(0., 0., 0.);
#ifdef DRAW_BOUNDARIES
glColor3f (1., 1., 1.);
DrawCircle (ship->mPhysicState->mRadius, 20);
#endif
}
void View::DrawAsteroid (AsteroidEntity *asteroid) {
mAsteroidSprite.SetScale (2. * asteroid->mPhysicState->mRadius / mAsteroidSprite.GetWidth());
mAsteroidSprite.DrawAt(0., 0., 0.);
#ifdef DRAW_BOUNDARIES
glColor3f (1., 1., 1.);
DrawCircle (asteroid->mPhysicState->mRadius, 20);
#endif
}
void View::DrawRocket (RocketEntity *rocket) {
glColor3f (1., 1., 1.);
glBegin (GL_QUADS);
glVertex3f (-0.25, 0., 0.05);
glVertex3f (0.05, 0., 0.05);
glVertex3f (0.05, 0., -0.05);
glVertex3f (-0.25, 0., -0.05);
glEnd ();
}
void View::DrawShipPart (Engine::EntityBase *entity) {
unsigned int i;
mShipPartsSprite.SetScale (1. / mShipSprite.GetHeight());
for (i = 0; i < mShipPartsEntityIds.size(); i++) {
if (mShipPartsEntityIds.at(i) == entity->mId) {
mShipPartsSprite.DrawSubAt (i, 0., 0., 0.);
}
}
#ifdef DRAW_BOUNDARIES
glColor3f (1., 1., 1.);
DrawCircle (entity->mPhysicState->mRadius, 20);
#endif
}
}
+75
View File
@@ -0,0 +1,75 @@
#ifndef _VIEW_H
#define _VIEW_H
#include "ViewBase.h"
#include "mathlib.h"
#include "Sprite.h"
#include "EntityBase.h"
namespace asteroids {
class MenuOverlay;
struct ShipEntity;
struct AsteroidEntity;
struct RocketEntity;
struct BackgroundStar {
vector3d position;
};
/** \brief Performs the actual drawing based on Camera and Model
*/
class View : public Engine::ViewBase {
protected:
/** \brief Initializes the system */
int OnInit (int argc, char* argv[]);
void OnDestroy ();
/** \brief Updates the camera for further drawing */
virtual void UpdateCamera ();
private:
virtual void DrawWorld ();
void DrawStars ();
void DrawEntity (Engine::EntityBase *entity);
void DrawShip (ShipEntity *ship);
void DrawAsteroid (AsteroidEntity *asteroid);
void DrawRocket (RocketEntity *asteroid);
void DrawShipPart (Engine::EntityBase *entity);
MenuOverlay *mMenuOverlay;
std::vector<BackgroundStar> mBackgroundStars;
std::vector<unsigned int> mShipPartsEntityIds;
Engine::Sprite mAsteroidSprite;
Engine::Sprite mShipSprite;
Engine::Sprite mShipThrustSprite;
Engine::Sprite mShipPartsSprite;
class AccelerateEventHandler : public Engine::EventListenerBase {
public:
explicit AccelerateEventHandler (View *view) : mView (view) {};
virtual bool HandleEvent (const Engine::EventBasePtr &event) const;
private:
View *mView;
};
class ShipExplodeEventHandler : public Engine::EventListenerBase {
public:
explicit ShipExplodeEventHandler (View *view) : mView (view) {};
virtual bool HandleEvent (const Engine::EventBasePtr &event) const;
private:
View *mView;
};
AccelerateEventHandler *mAccelerateEventHandler;
ShipExplodeEventHandler *mShipExplodeEventHandler;
friend class AccelerateEventHandler;
};
}
#endif // _VIEW_H
+44
View File
@@ -0,0 +1,44 @@
#include <cstdlib>
#include <iostream>
#include "Engine.h"
#include "Controller.h"
#include "View.h"
#include "Model.h"
#include "Physics.h"
#include "EntityFactory.h"
using namespace std;
int main (int argc, char* argv[]) {
cout << "Game Start" << endl;
Engine::Engine engine;
engine.SetEntityFactory (new asteroids::EntityFactory);
engine.SetController (new asteroids::Controller);
engine.SetModel (new asteroids::Model);
engine.SetPhysics (new asteroids::Physics);
engine.SetView (new asteroids::View);
SetLogPrintLevel (Engine::LogLevelDebug);
if (engine.Init (argc, argv) != 0) {
cout << "Could not start engine!" << endl;
exit (-1);
}
engine.GetView()->SetGridSize (8,8);
dynamic_cast<asteroids::Physics*>(engine.GetPhysics())->SetWorldSize (28, 20);
SetLogPrintLevel (Engine::LogLevelDebug);
engine.MainLoop ();
engine.Destroy ();
cout << "Game Quit" << endl;
return 0;
}