360 lines
10 KiB
C++
360 lines
10 KiB
C++
|
#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
|
||
|
}
|
||
|
|
||
|
}
|