summaryrefslogtreecommitdiff
path: root/src/game.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game.cpp')
-rw-r--r--src/game.cpp278
1 files changed, 278 insertions, 0 deletions
diff --git a/src/game.cpp b/src/game.cpp
new file mode 100644
index 0000000..a2aa491
--- /dev/null
+++ b/src/game.cpp
@@ -0,0 +1,278 @@
+/*********************************************************************
+ * File: game.cpp
+ * Description: Contains the implementaiton of the game class
+ * methods.
+ *
+ *********************************************************************/
+
+#include "game.h"
+#include "uiDraw.h"
+#include "bullet.h"
+// These are needed for the getClosestDistance function...
+#include <limits>
+#include <iostream>
+#include <algorithm>
+#define CLOSE_ENOUGH 15
+using namespace std;
+
+// Game non-default constructor
+Game :: Game ( const Point &tl , const Point &br ) : topLeft ( tl ) , bottomRight ( br )
+{
+ rocks = createRocks();
+ ship = new Ship ( Point() );
+}
+
+// Create rocks for the game
+vector<Rock *> Game :: createRocks()
+{
+ vector<Rock *> initRocks;
+ for ( int i = 0; i < random ( 5 , 8 ); i++ )
+ {
+ Point rockPoint = Point ( random( -190 , 190 ) , random ( -190 , 190 ) );
+ Velocity velocity;
+ velocity.setDx ( random ( -3.0 , 3.0 ) );
+ velocity.setDy ( random ( -2.0 , 2.0 ) );
+ // Make sure spawn is safe on start by calculating if
+ // The rock is on a trajectory to the ship
+ float m = velocity.getDy() / velocity.getDx();
+
+ if ( fabs ( rockPoint.getY() - m * rockPoint.getX() ) >= 50 )
+ {
+ switch ( random( 1 , 5 ) ) {
+ case 1:
+ case 2:
+ case 3:
+ initRocks.push_back ( new BigRock ( rockPoint , velocity ) );
+ break;
+ case 4:
+ initRocks.push_back ( new MediumRock ( rockPoint , velocity ) );
+ break;
+ case 5:
+ initRocks.push_back ( new SmallRock ( rockPoint , velocity ) );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return initRocks;
+}
+
+// Get closest distance between two flying objects
+float Game :: getClosestDistance(const FlyingObject &obj1, const FlyingObject &obj2) const
+{
+ // find the maximum distance traveled
+ float dMax = max(abs(obj1.getVelocity().getDx()), abs(obj1.getVelocity().getDy()));
+ dMax = max(dMax, abs(obj2.getVelocity().getDx()));
+ dMax = max(dMax, abs(obj2.getVelocity().getDy()));
+ dMax = max(dMax, 0.1f); // when dx and dy are 0.0. Go through the loop once.
+
+ float distMin = std::numeric_limits<float>::max();
+ for (float i = 0.0; i <= dMax; i++)
+ {
+ Point point1(obj1.getPoint().getX() + (obj1.getVelocity().getDx() * i / dMax),
+ obj1.getPoint().getY() + (obj1.getVelocity().getDy() * i / dMax));
+ Point point2(obj2.getPoint().getX() + (obj2.getVelocity().getDx() * i / dMax),
+ obj2.getPoint().getY() + (obj2.getVelocity().getDy() * i / dMax));
+
+ float xDiff = point1.getX() - point2.getX();
+ float yDiff = point1.getY() - point2.getY();
+
+ float distSquared = (xDiff * xDiff) +(yDiff * yDiff);
+
+ distMin = min(distMin, distSquared);
+ }
+
+ return sqrt(distMin);
+}
+
+// Advance everything in the game
+void Game :: advance()
+{
+ cleanUpZombies();
+ advanceShip();
+ advanceBullets();
+ advanceAsteroids();
+
+ handleCollisions();
+}
+
+// Advance all asteroids in game
+void Game :: advanceAsteroids()
+{
+ for ( int i = 0; i < rocks.size(); i++ )
+ {
+ rocks[i]->advance();
+ }
+}
+
+// Advance all the bullets
+void Game :: advanceBullets()
+{
+ for ( int i = 0; i < bullets.size(); i++ )
+ {
+ bullets[i]->advance();
+ }
+}
+
+// Advance the ship
+void Game :: advanceShip()
+{
+ if ( ship->isAlive() && ship->getFuel() >= 0 )
+ {
+ ship->advance();
+ }
+}
+
+// Clean up memory
+void Game :: cleanUpZombies()
+{
+ for ( int i = 0; i < bullets.size(); i++ )
+ {
+ if ( !bullets[i]->isAlive() )
+ {
+ delete bullets[i];
+ bullets[i] = NULL;
+ bullets.erase( bullets.begin() + i );
+ }
+ }
+ for ( int i = 0; i < rocks.size(); i++ )
+ {
+ if ( !rocks[i]->isAlive() )
+ {
+ delete rocks[i];
+ rocks[i] = NULL;
+ rocks.erase( rocks.begin() + i );
+ }
+ }
+}
+
+// Handle all collisions
+void Game :: handleCollisions()
+{
+ // Handle bullet collisions
+ for ( int i = 0; i < rocks.size(); i++ )
+ {
+ Rock * rock = rocks[i];
+ if ( rock->isAlive() )
+ {
+ for ( int j = 0; j < bullets.size(); j++ )
+ {
+ Bullet * bullet = bullets[j];
+ if ( bullet->isAlive() )
+ {
+ float allowedRange = rock->getSize() + CLOSE_ENOUGH;
+ if ( fabs( getClosestDistance( *bullet , *rock ) ) < allowedRange
+ || bullet->getPoint().inRange( rock->getPoint() , allowedRange ) )
+ {
+ vector<Rock *> newRocks = rock->destroy();
+ for ( int i = 0; i < newRocks.size(); i++ )
+ {
+ rocks.push_back ( newRocks[i] );
+ }
+ rock->kill();
+ bullet->kill();
+ }
+ }
+ }
+ }
+ }
+
+ // Handle ship collisions
+ for ( int i = 0; i < rocks.size(); i++ )
+ {
+ Rock * rock = rocks[i];
+ if ( rock->isAlive() && ship->isAlive() )
+ {
+ float allowedRange = rock->getSize() + CLOSE_ENOUGH;
+ if ( fabs( getClosestDistance( *ship , *rock ) ) < allowedRange
+ || ship->getPoint().inRange( rock->getPoint() , allowedRange ) )
+ {
+ vector<Rock *> newRocks = rock->destroy();
+ for ( int i = 0; i < newRocks.size(); i++ )
+ {
+ rocks.push_back ( newRocks[i] );
+ }
+ rock->kill();
+ ship->kill();
+ }
+ }
+ }
+ cleanUpZombies();
+}
+
+// Draw everything
+void Game :: draw ( const Interface &ui )
+{
+ drawRocks();
+ drawShip();
+ drawBullets();
+ drawNumber ( Point ( -170 , 170 ) , (int) ship->getFuel() );
+ drawText ( Point ( -170 , 180 ) , "FUEL:" );
+}
+
+// Draw rocks
+void Game :: drawRocks()
+{
+ for ( int i = 0; i < rocks.size(); i++ )
+ {
+ rocks[i]->draw();
+ }
+}
+
+// Draw ship
+void Game :: drawShip()
+{
+ if ( ship->isAlive() )
+ {
+ ship->draw();
+ }
+}
+
+// Draw bullets
+void Game :: drawBullets()
+{
+ for ( int i = 0; i < bullets.size(); i++ )
+ {
+ bullets[i]->draw();
+ }
+}
+
+// Handle in-game input
+void Game::handleInput(const Interface & ui)
+{
+ if ( ship->isAlive() )
+ {
+ if ( ui.isUp() )
+ {
+ ship->setThrusting ( true );
+ ship->thrust( true );
+ }
+ if ( ui.isDown() )
+ {
+ ship->setThrusting ( true );
+ ship->thrust( false );
+ }
+ if ( ui.isLeft() )
+ {
+ ship->setThrusting ( true );
+ ship->rotate( true );
+ }
+ if ( ui.isRight() )
+ {
+ ship->setThrusting ( true );
+ ship->rotate( false );
+ }
+ if ( ui.isSpace() )
+ {
+ Bullet * newBullet = new Bullet( ship->getPoint() );
+ newBullet->fire( ship->getVelocity(), ship->getAngle() );
+ bullets.push_back( newBullet );
+ }
+ if ( !ui.isRight() && !ui.isUp() && !ui.isDown() && !ui.isLeft() )
+ {
+ ship->setThrusting ( false );
+ }
+ }
+
+}