summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimponic <loganthebean222@gmail.com>2020-06-30 20:04:55 -0600
committerSimponic <loganthebean222@gmail.com>2020-06-30 20:04:55 -0600
commit7a60ab9f178dd813c876fcf8e25c947f9a9a5e06 (patch)
tree31ec5147b0e6a01b85499cf06a701af750fb83f7
downloadasteroids-cs165-7a60ab9f178dd813c876fcf8e25c947f9a9a5e06.tar.gz
asteroids-cs165-7a60ab9f178dd813c876fcf8e25c947f9a9a5e06.zip
Updated indentation
-rw-r--r--LICENSE21
-rw-r--r--README.md2
-rw-r--r--bullet.cpp29
-rw-r--r--bullet.h24
-rw-r--r--driver.cpp45
-rw-r--r--flyingObject.cpp20
-rw-r--r--flyingObject.h28
-rw-r--r--game.cpp278
-rw-r--r--game.h53
-rw-r--r--makefile71
-rw-r--r--point.cpp77
-rw-r--r--point.h49
-rw-r--r--rocks.cpp63
-rw-r--r--rocks.h84
-rw-r--r--ship.cpp36
-rw-r--r--ship.h32
-rw-r--r--uiDraw.cpp714
-rw-r--r--uiDraw.h135
-rw-r--r--uiInteract.cpp326
-rw-r--r--uiInteract.h131
-rw-r--r--velocity.cpp59
-rw-r--r--velocity.h23
22 files changed, 2300 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..bc341d0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Logan Hunt
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9653d82
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# Asteroids-CPP
+The game asteroids in c++ using the simplified drawing library provided by my school.
diff --git a/bullet.cpp b/bullet.cpp
new file mode 100644
index 0000000..69fb603
--- /dev/null
+++ b/bullet.cpp
@@ -0,0 +1,29 @@
+#include "bullet.h"
+#include "ship.h"
+#include <cmath>
+
+#define M_PI 3.14159265
+
+// Bullet non-default constructor
+Bullet :: Bullet( const Point &point ) : FlyingObject() , framesAlive( 0 )
+{
+ setPoint ( point );
+}
+
+// Fire Bullet
+void Bullet :: fire ( const Velocity &vel , const float angle )
+{
+ velocity.setDx ( BULLET_SPEED * ( -cos ( M_PI / 180 * angle ) ) );
+ velocity.setDy ( BULLET_SPEED * ( sin ( M_PI / 180 * angle ) ) );
+}
+
+// Advance Bullet
+void Bullet :: advance ()
+{
+ framesAlive++;
+ if ( framesAlive >= 40 )
+ {
+ kill();
+ }
+ FlyingObject :: advance();
+}
diff --git a/bullet.h b/bullet.h
new file mode 100644
index 0000000..3392ee4
--- /dev/null
+++ b/bullet.h
@@ -0,0 +1,24 @@
+#ifndef bullet_h
+#define bullet_h
+
+#define BULLET_SPEED 10
+#define BULLET_LIFE 40
+
+#include "point.h"
+#include "velocity.h"
+#include "flyingObject.h"
+
+class Bullet : public FlyingObject
+{
+private:
+ int framesAlive;
+
+public:
+ Bullet( const Point &point );
+ int getFramesAlive() const { return framesAlive; };
+ void fire( const Velocity &velocity , const float angle );
+ void advance();
+};
+
+
+#endif /* bullet_h */
diff --git a/driver.cpp b/driver.cpp
new file mode 100644
index 0000000..5e1b9a5
--- /dev/null
+++ b/driver.cpp
@@ -0,0 +1,45 @@
+/*****************************************************
+ * File: Driver.cpp
+ * Author: Br. Burton
+ *
+ * Description: This file contains the main function
+ * that starts the game and the callback function
+ * that specifies what methods of the game class are
+ * called each time through the game loop.
+ ******************************************************/
+#include "game.h"
+#include "uiInteract.h"
+
+/*************************************
+ * All the interesting work happens here, when
+ * I get called back from OpenGL to draw a frame.
+ * When I am finished drawing, then the graphics
+ * engine will wait until the proper amount of
+ * time has passed and put the drawing on the screen.
+ **************************************/
+void callBack(const Interface *pUI, void *p)
+{
+ Game *pGame = (Game *)p;
+
+ pGame->advance();
+ pGame->draw(*pUI);
+ pGame->handleInput(*pUI);
+}
+
+
+/*********************************
+ * Main is pretty sparse. Just initialize
+ * the game and call the display engine.
+ * That is all!
+ *********************************/
+int main(int argc, char ** argv)
+{
+ Point topLeft(-200, 200);
+ Point bottomRight(200, -200);
+
+ Interface ui(argc, argv, "Asteroids", topLeft, bottomRight);
+ Game game(topLeft, bottomRight);
+ ui.run(callBack, &game);
+
+ return 0;
+}
diff --git a/flyingObject.cpp b/flyingObject.cpp
new file mode 100644
index 0000000..149e3f5
--- /dev/null
+++ b/flyingObject.cpp
@@ -0,0 +1,20 @@
+#include "flyingObject.h"
+#include <iostream>
+
+// Advance flyingobjects
+void FlyingObject::advance()
+{
+ point.addX( getVelocity().getDx() );
+ point.addY( getVelocity().getDy() );
+
+ if ( point.getX() > 200 )
+ point.setX( -200 );
+ else if ( point.getX() < -200 )
+ point.setX( 200 );
+
+ if ( point.getY() > 200 )
+ point.setY( -200 );
+ else if ( point.getY() < -200 )
+ point.setY( 200 );
+
+}
diff --git a/flyingObject.h b/flyingObject.h
new file mode 100644
index 0000000..2e77e5e
--- /dev/null
+++ b/flyingObject.h
@@ -0,0 +1,28 @@
+#ifndef flyingObject_h
+#define flyingObject_h
+
+#include "point.h"
+#include "velocity.h"
+#include "uiDraw.h"
+
+class FlyingObject
+{
+protected:
+ Point point;
+ Velocity velocity
+ bool alive;
+public:
+ FlyingObject() : point( Point() ) , velocity( Velocity() ) , alive( true ) {}
+ Point getPoint() const { return this->point; }
+ void setPoint( const Point &point ) { this->point = point; }
+ Velocity getVelocity() const { return this->velocity; }
+ void setVelocity( const Velocity &velocity) { this->velocity = velocity; }
+ bool isAlive() { return this->alive; }
+ void kill() { alive = false; };
+ virtual void draw() { drawDot( point ); };
+ virtual void advance();
+};
+
+
+
+#endif /* flyingObject_h */
diff --git a/game.cpp b/game.cpp
new file mode 100644
index 0000000..a2aa491
--- /dev/null
+++ b/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 );
+ }
+ }
+
+}
diff --git a/game.h b/game.h
new file mode 100644
index 0000000..d64efc6
--- /dev/null
+++ b/game.h
@@ -0,0 +1,53 @@
+/*********************************************************************
+ * File: game.h
+ * Description: Defines the game class for Asteroids
+ *
+ *********************************************************************/
+
+#ifndef GAME_H
+#define GAME_H
+
+#include <vector>
+#include "bullet.h"
+#include "ship.h"
+#include "rocks.h"
+#include "uiDraw.h"
+#include "uiInteract.h"
+
+#define CLOSE_ENOUGH 15
+
+using namespace std;
+
+class Game
+{
+private:
+ Point topLeft;
+ Point bottomRight;
+ vector<Rock *> rocks;
+ vector<Bullet *> bullets;
+ Ship* ship;
+
+ float getClosestDistance( const FlyingObject &obj1 , const FlyingObject &obj2 ) const;
+
+ vector<Rock *> createRocks();
+
+ void advanceBullets();
+ void advanceAsteroids();
+ void advanceShip();
+
+ void cleanUpZombies();
+
+ void handleCollisions();
+
+ void drawBullets();
+ void drawRocks();
+ void drawShip();
+public:
+ Game ( const Point &tl , const Point &br );
+ void handleInput ( const Interface &ui );
+ void draw ( const Interface &ui );
+ void advance();
+};
+
+
+#endif /* GAME_H */
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..22b20f7
--- /dev/null
+++ b/makefile
@@ -0,0 +1,71 @@
+# Author:
+# Logan Hunt
+# Summary:
+# Play the game asteroids
+# Above and Beyond
+# Changed colors
+# Added fuel
+# rotation: -1 units/frame
+# movement: -3 units/frame
+# Made sure that initially, trajectories of rocks will
+# not hit ship
+# There's a chance of medium asteroids spawning at the start
+# The initial amount of large rocks is random
+###############################################################
+
+
+LFLAGS = -lglut -lGLU -lGL
+
+###############################################################
+# Build the main game
+###############################################################
+a.out: driver.o game.o uiInteract.o uiDraw.o point.o velocity.o flyingObject.o ship.o bullet.o rocks.o
+ g++ driver.o game.o uiInteract.o uiDraw.o point.o velocity.o flyingObject.o ship.o bullet.o rocks.o $(LFLAGS)
+
+###############################################################
+# Individual files
+# uiDraw.o Draw polygons on the screen and do all OpenGL graphics
+# uiInteract.o Handles input events
+# point.o The position on the screen
+# game.o Handles the game interaction
+# velocity.o Velocity (speed and direction)
+# flyingObject.o Base class for all flying objects
+# ship.o The player's ship
+# bullet.o The bullets fired from the ship
+# rocks.o Contains all of the Rock classes
+###############################################################
+uiDraw.o: uiDraw.cpp uiDraw.h
+ g++ -c uiDraw.cpp
+
+uiInteract.o: uiInteract.cpp uiInteract.h
+ g++ -c uiInteract.cpp
+
+point.o: point.cpp point.h
+ g++ -c point.cpp
+
+driver.o: driver.cpp game.h
+ g++ -c driver.cpp
+
+game.o: game.cpp game.h uiDraw.h uiInteract.h point.h velocity.h flyingObject.h bullet.h rocks.h ship.h
+ g++ -c game.cpp
+
+velocity.o: velocity.cpp velocity.h point.h
+ g++ -c velocity.cpp
+
+flyingObject.o: flyingObject.cpp flyingObject.h point.h velocity.h uiDraw.h
+ g++ -c flyingObject.cpp
+
+ship.o: ship.cpp ship.h flyingObject.h point.h velocity.h uiDraw.h
+ g++ -c ship.cpp
+
+bullet.o: bullet.cpp bullet.h flyingObject.h point.h velocity.h uiDraw.h
+ g++ -c bullet.cpp
+
+rocks.o: rocks.cpp rocks.h flyingObject.h point.h velocity.h uiDraw.h
+ g++ -c rocks.cpp
+
+###############################################################
+# General rules
+###############################################################
+clean:
+ rm a.out *.o
diff --git a/point.cpp b/point.cpp
new file mode 100644
index 0000000..cad96e4
--- /dev/null
+++ b/point.cpp
@@ -0,0 +1,77 @@
+/***********************************************************************
+ * Source File:
+ * Point : The representation of a position on the screen
+ * Author:
+ * Br. Helfrich
+ * Summary:
+ * Everything we need to know about a location on the screen, including
+ * the location and the bounds.
+ ************************************************************************/
+
+#include "point.h"
+#include <cassert>
+#include "uiDraw.h"
+using namespace std;
+/******************************************
+ * POINT : CONSTRUCTOR WITH X,Y
+ * Initialize the point to the passed position
+ *****************************************/
+Point::Point(float x, float y) : x(0.0), y(0.0)
+{
+ setX(x);
+ setY(y);
+}
+
+/*******************************************
+ * POINT : SET X
+ * Set the x position if the value is within range
+ *******************************************/
+void Point::setX(float x)
+{
+ this->x = x;
+}
+
+/*******************************************
+ * POINT : SET Y
+ * Set the y position if the value is within range
+ *******************************************/
+void Point::setY(float y)
+{
+ this->y = y;
+}
+
+/******************************************
+ * POINT insertion
+ * Display coordinates on the screen
+ *****************************************/
+std::ostream & operator << (std::ostream & out, const Point & pt)
+{
+ out << "(" << pt.getX() << ", " << pt.getY() << ")";
+ return out;
+}
+
+/*******************************************
+ * POINT extraction
+ * Prompt for coordinates
+ ******************************************/
+std::istream & operator >> (std::istream & in, Point & pt)
+{
+ float x;
+ float y;
+ in >> x >> y;
+
+ pt.setX(x);
+ pt.setY(y);
+
+ return in;
+}
+
+bool Point::inRange( const Point &p, const float range )
+{
+ if ( ( fabs( getX() - p.getX() ) < range) &&
+ ( fabs( getY() - p.getY() ) < range ) )
+ {
+ return true;
+ }
+ return false;
+}
diff --git a/point.h b/point.h
new file mode 100644
index 0000000..7f0715f
--- /dev/null
+++ b/point.h
@@ -0,0 +1,49 @@
+/***********************************************************************
+ * Header File:
+ * Point : The representation of a position on the screen
+ * Author:
+ * Br. Helfrich
+ * Summary:
+ * Everything we need to know about a location on the screen, including
+ * the location and the bounds.
+ ************************************************************************/
+
+
+#ifndef POINT_H
+#define POINT_H
+
+#include <iostream>
+
+/*********************************************
+ * POINT
+ * A single position.
+ *********************************************/
+class Point
+{
+public:
+ // constructors
+ Point() : x(0.0), y(0.0) {}
+ Point(bool check) : x(0.0), y(0.0) {}
+ Point(float x, float y);
+
+ // getters
+ float getX() const { return x; }
+ float getY() const { return y; }
+
+ // setters
+ void setX(float x);
+ void setY(float y);
+ void addX(float dx) { setX(getX() + dx); }
+ void addY(float dy) { setY(getY() + dy); }
+
+ bool inRange ( const Point &p , const float range );
+private:
+ float x; // horizontal position
+ float y; // vertical position
+};
+
+// stream I/O useful for debugging
+std::ostream & operator << (std::ostream & out, const Point & pt);
+std::istream & operator >> (std::istream & in, Point & pt);
+
+#endif // POINT_H
diff --git a/rocks.cpp b/rocks.cpp
new file mode 100644
index 0000000..7c3c13e
--- /dev/null
+++ b/rocks.cpp
@@ -0,0 +1,63 @@
+#include "rocks.h"
+#include "uiDraw.h"
+#include <cmath>
+#define M_PI 3.14159265
+
+// Destroy Big Rock and return vector of new *rocks
+vector<Rock *> BigRock :: destroy()
+{
+ vector<Rock *> rocks;
+ Velocity rockVel = this->velocity;
+ Point rockPoint = this->point;
+
+ rockVel.addDy ( 1 );
+ rocks.push_back ( new MediumRock ( rockPoint , rockVel ) );
+
+ rockVel.addDy ( -2 ); // Original rockvel dy - 1
+ rocks.push_back ( new MediumRock ( rockPoint , rockVel ) );
+
+ rockVel.addDy ( 1 ); // Original rockvel dy
+ rockVel.addDx ( (float) random ( 1.0 , 3.0 ) );
+ rocks.push_back ( new SmallRock ( rockPoint , rockVel ) );
+
+ return rocks;
+}
+
+// Draw big rock
+void BigRock :: draw()
+{
+ drawLargeAsteroid ( this->point , this->angle );
+}
+
+// Destroy Medium Rock and return vector of new *rocks
+vector<Rock *> MediumRock :: destroy()
+{
+ vector<Rock *> rocks;
+ Velocity rockVel = this->velocity;
+ Point rockPoint = this->point;
+
+ rockVel.addDx ( 3 );
+ rocks.push_back ( new SmallRock ( rockPoint , rockVel ) );
+ rockVel.addDx ( -6 );
+ rocks.push_back ( new SmallRock ( rockPoint , rockVel ) );
+
+ return rocks;
+}
+
+// Draw Medium Rock
+void MediumRock :: draw()
+{
+ drawMediumAsteroid ( this->point , this->angle );
+}
+
+// Destroy Small Rock and return an empty *rock vector
+vector<Rock *> SmallRock :: destroy()
+{
+ return vector<Rock *>();
+}
+
+// Draw small rock
+void SmallRock :: draw()
+{
+ drawSmallAsteroid ( this->point , this->angle );
+}
diff --git a/rocks.h b/rocks.h
new file mode 100644
index 0000000..ae12e2b
--- /dev/null
+++ b/rocks.h
@@ -0,0 +1,84 @@
+#ifndef rocks_h
+#define rocks_h
+
+#define BIG_ROCK_SIZE 16
+#define MEDIUM_ROCK_SIZE 8
+#define SMALL_ROCK_SIZE 4
+
+#define BIG_ROCK_SPIN 2
+#define MEDIUM_ROCK_SPIN 5
+#define SMALL_ROCK_SPIN 10
+
+#include "flyingObject.h"
+#include <vector>
+
+using namespace std;
+
+class Rock : public FlyingObject
+{
+protected:
+ int rotationDegPerFrame;
+ int size;
+ float angle;
+public:
+ Rock() : FlyingObject() , rotationDegPerFrame ( 0 ) , size ( 1 ) , angle ( 0 ) {}
+ Rock ( int degPerFrame , int size , float angle ) : rotationDegPerFrame ( degPerFrame ) , size ( size ) , angle ( angle ) {}
+
+ int getRotationDegPerFrame() { return rotationDegPerFrame; }
+ int getSize () { return size; }
+ float getAngle() { return angle; }
+
+ void setAngle ( const float angle ) { this->angle = angle; }
+ void setRotationDegPerFrame ( const int degPerFrame ) { this->rotationDegPerFrame = degPerFrame; }
+ void setSize ( const int size ) { this->size = size; }
+ void advance() { this->angle += rotationDegPerFrame; FlyingObject::advance(); }
+ virtual void draw() {};
+ virtual vector<Rock *> destroy() = 0;
+};
+
+class BigRock : public Rock
+{
+public:
+ BigRock ( const Point &point , const Velocity &velocity )
+ {
+ setPoint ( point );
+ setAngle ( 0 );
+ setSize ( BIG_ROCK_SIZE );
+ setRotationDegPerFrame ( BIG_ROCK_SPIN );
+ setAngle ( random ( 0 , 360 ) );
+ setVelocity ( velocity );
+ }
+
+ vector<Rock *> destroy();
+ void draw();
+};
+
+class MediumRock : public Rock
+{
+public:
+ MediumRock ( const Point &point , const Velocity &vel ) {
+ this->point = point;
+ this->velocity = vel;
+ setAngle ( 0 );
+ setRotationDegPerFrame ( MEDIUM_ROCK_SPIN );
+ setSize ( MEDIUM_ROCK_SIZE );
+ }
+ vector<Rock *> destroy();
+ void draw();
+};
+
+class SmallRock : public Rock
+{
+public:
+ SmallRock( const Point &point , const Velocity &vel ) {
+ this->point = point;
+ this->velocity = vel;
+ setAngle ( 0 );
+ setRotationDegPerFrame ( SMALL_ROCK_SPIN );
+ setSize ( SMALL_ROCK_SIZE );
+ }
+ vector<Rock *> destroy();
+ void draw();
+};
+
+#endif /* rocks_h */
diff --git a/ship.cpp b/ship.cpp
new file mode 100644
index 0000000..2eaa852
--- /dev/null
+++ b/ship.cpp
@@ -0,0 +1,36 @@
+#include "ship.h"
+#include "bullet.h"
+
+#include <cmath>
+
+#define M_PI 3.14159265
+// Put your ship methods here
+
+// Apply thrust to ship
+void Ship :: thrust ( const bool isUp )
+{
+ float thrust = THRUST_AMOUNT * ( isUp ? 1 : -1 );
+ fuel -= 3;
+ if ( fuel >= 0 )
+ {
+ velocity.addDx ( thrust * ( -cos ( M_PI / 180 * angle ) ) );
+ velocity.addDy ( thrust * ( sin ( M_PI / 180 * angle ) ) );
+ }
+ else
+ {
+ fuel = 0; // In the case of negative fuel
+ }
+}
+
+// Rotate ship
+void Ship :: rotate ( const bool isRight )
+{
+ angle += ROTATE_AMOUNT * ( isRight ? -1 : 1 );
+ fuel -= 1;
+}
+
+// Draw ship
+void Ship :: draw ( ) const
+{
+ drawShip ( getPoint() , -(angle - 90) , isThrusting );
+}
diff --git a/ship.h b/ship.h
new file mode 100644
index 0000000..46b6817
--- /dev/null
+++ b/ship.h
@@ -0,0 +1,32 @@
+#ifndef ship_h
+#define ship_h
+
+#define SHIP_SIZE 10
+#define ROTATE_AMOUNT 6
+#define THRUST_AMOUNT 0.5
+
+#include "flyingObject.h"
+#include "uiDraw.h"
+#include "uiInteract.h"
+
+using namespace std;
+
+class Ship : public FlyingObject
+{
+private:
+ float angle;
+ bool isThrusting;
+ int fuel;
+public:
+ Ship( const Point &point ) : FlyingObject() , fuel ( 1000 ) , angle ( 90.0 ) , isThrusting( false ) { setPoint ( point ); }
+ float getAngle() const { return this->angle; }
+ float getFuel() { return this->fuel; }
+ void setFuel ( const int fuel ) { this->fuel - fuel; }
+ void thrust( const bool isUp );
+ void rotate( const bool isRight );
+ bool getIsThrusting() { return isThrusting; }
+ void setThrusting( const bool isThrusting ) { this->isThrusting = isThrusting; }
+ void draw() const;
+};
+
+#endif /* ship_h */
diff --git a/uiDraw.cpp b/uiDraw.cpp
new file mode 100644
index 0000000..6d36f24
--- /dev/null
+++ b/uiDraw.cpp
@@ -0,0 +1,714 @@
+/***********************************************************************
+ * Source File:
+ * User Interface Draw : put pixels on the screen
+ * Author:
+ * Br. Helfrich
+ * Summary:
+ * This is the code necessary to draw on the screen. We have a collection
+ * of procedural functions here because each draw function does not
+ * retain state. In other words, they are verbs (functions), not nouns
+ * (variables) or a mixture (objects)
+ ************************************************************************/
+
+#include <string> // need you ask?
+#include <sstream> // convert an integer into text
+#include <cassert> // I feel the need... the need for asserts
+#include <time.h> // for clock
+
+
+#ifdef __APPLE__
+#include <openGL/gl.h> // Main OpenGL library
+#include <GLUT/glut.h> // Second OpenGL library
+#endif // __APPLE__
+
+#ifdef __linux__
+#include <GL/gl.h> // Main OpenGL library
+#include <GL/glut.h> // Second OpenGL library
+#endif // __linux__
+
+#ifdef _WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/glut.h> // OpenGL library we copied
+#define _USE_MATH_DEFINES
+#include <math.h>
+#endif // _WIN32
+
+#include "point.h"
+#include "uiDraw.h"
+
+using namespace std;
+
+#define deg2rad(value) ((M_PI / 180) * (value))
+
+/*********************************************
+ * NUMBER OUTLINES
+ * We are drawing the text for score and things
+ * like that by hand to make it look "old school."
+ * These are how we render each individual charactger.
+ * Note how -1 indicates "done". These are paired
+ * coordinates where the even are the x and the odd
+ * are the y and every 2 pairs represents a point
+ ********************************************/
+const char NUMBER_OUTLINES[10][20] =
+{
+ {0, 0, 7, 0, 7, 0, 7,10, 7,10, 0,10, 0,10, 0, 0, -1,-1, -1,-1},//0
+ {7, 0, 7,10, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1},//1
+ {0, 0, 7, 0, 7, 0, 7, 5, 7, 5, 0, 5, 0, 5, 0,10, 0,10, 7,10},//2
+ {0, 0, 7, 0, 7, 0, 7,10, 7,10, 0,10, 4, 5, 7, 5, -1,-1, -1,-1},//3
+ {0, 0, 0, 5, 0, 5, 7, 5, 7, 0, 7,10, -1,-1, -1,-1, -1,-1, -1,-1},//4
+ {7, 0, 0, 0, 0, 0, 0, 5, 0, 5, 7, 5, 7, 5, 7,10, 7,10, 0,10},//5
+ {7, 0, 0, 0, 0, 0, 0,10, 0,10, 7,10, 7,10, 7, 5, 7, 5, 0, 5},//6
+ {0, 0, 7, 0, 7, 0, 7,10, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1},//7
+ {0, 0, 7, 0, 0, 5, 7, 5, 0,10, 7,10, 0, 0, 0,10, 7, 0, 7,10},//8
+ {0, 0, 7, 0, 7, 0, 7,10, 0, 0, 0, 5, 0, 5, 7, 5, -1,-1, -1,-1} //9
+};
+
+/************************************************************************
+ * DRAW DIGIT
+ * Draw a single digit in the old school line drawing style. The
+ * size of the glyph is 8x11 or x+(0..7), y+(0..10)
+ * INPUT topLeft The top left corner of the character
+ * digit The digit we are rendering: '0' .. '9'
+ *************************************************************************/
+void drawDigit(const Point & topLeft, char digit)
+{
+ // we better be only drawing digits
+ assert(isdigit(digit));
+ if (!isdigit(digit))
+ return;
+
+ // compute the row as specified by the digit
+ int r = digit - '0';
+ assert(r >= 0 && r <= 9);
+
+ // go through each segment.
+ for (int c = 0; c < 20 && NUMBER_OUTLINES[r][c] != -1; c += 4)
+ {
+ assert(NUMBER_OUTLINES[r][c ] != -1 &&
+ NUMBER_OUTLINES[r][c + 1] != -1 &&
+ NUMBER_OUTLINES[r][c + 2] != -1 &&
+ NUMBER_OUTLINES[r][c + 3] != -1);
+
+ //Draw a line based off of the num structure for each number
+ Point start;
+ start.setX(topLeft.getX() + NUMBER_OUTLINES[r][c]);
+ start.setY(topLeft.getY() - NUMBER_OUTLINES[r][c + 1]);
+ Point end;
+ end.setX(topLeft.getX() + NUMBER_OUTLINES[r][c + 2]);
+ end.setY(topLeft.getY() - NUMBER_OUTLINES[r][c + 3]);
+
+ drawLine(start, end);
+ }
+}
+
+/*************************************************************************
+ * DRAW NUMBER
+ * Display an integer on the screen using the 7-segment method
+ * INPUT topLeft The top left corner of the character
+ * digit The digit we are rendering: '0' .. '9'
+ *************************************************************************/
+void drawNumber(const Point & topLeft, int number)
+{
+ // our cursor, if you will. It will advance as we output digits
+ Point point = topLeft;
+
+ // is this negative
+ bool isNegative = (number < 0);
+ number *= (isNegative ? -1 : 1);
+
+ // render the number as text
+ ostringstream sout;
+ sout << number;
+ string text = sout.str();
+
+ // handle the negative
+ if (isNegative)
+ {
+ glBegin(GL_LINES);
+ glVertex2f(point.getX() + 1, point.getY() - 5);
+ glVertex2f(point.getX() + 5, point.getY() - 5);
+ glEnd();
+ point.addX(11);
+ }
+
+ // walk through the text one digit at a time
+ for (const char *p = text.c_str(); *p; p++)
+ {
+ assert(isdigit(*p));
+ drawDigit(point, *p);
+ point.addX(11);
+ }
+}
+
+
+/*************************************************************************
+ * DRAW TEXT
+ * Draw text using a simple bitmap font
+ * INPUT topLeft The top left corner of the text
+ * text The text to be displayed
+ ************************************************************************/
+void drawText(const Point & topLeft, const char * text)
+{
+ void *pFont = GLUT_BITMAP_HELVETICA_12; // also try _18
+
+ // prepare to draw the text from the top-left corner
+ glRasterPos2f(topLeft.getX(), topLeft.getY());
+
+ // loop through the text
+ for (const char *p = text; *p; p++)
+ glutBitmapCharacter(pFont, *p);
+}
+
+/************************************************************************
+ * DRAW POLYGON
+ * Draw a POLYGON from a given location (center) of a given size (radius).
+ * INPUT center Center of the polygon
+ * radius Size of the polygon
+ * points How many points will we draw it. Larger the number,
+ * the more line segments we will use
+ * rotation True circles are rotation independent. However, if you
+ * are drawing a 3-sided polygon (triangle), this matters!
+ *************************************************************************/
+void drawPolygon(const Point & center, int radius, int points, int rotation)
+{
+ // begin drawing
+ glBegin(GL_LINE_LOOP);
+
+ //loop around a circle the given number of times drawing a line from
+ //one point to the next
+ for (double i = 0; i < 2 * M_PI; i += (2 * M_PI) / points)
+ {
+ Point temp(false /*check*/);
+ temp.setX(center.getX() + (radius * cos(i)));
+ temp.setY(center.getY() + (radius * sin(i)));
+ rotate(temp, center, rotation);
+ glVertex2f(temp.getX(), temp.getY());
+ }
+
+ // complete drawing
+ glEnd();
+
+}
+
+
+/************************************************************************
+ * ROTATE
+ * Rotate a given point (point) around a given origin (center) by a given
+ * number of degrees (angle).
+ * INPUT point The point to be moved
+ * center The center point we will rotate around
+ * rotation Rotation in degrees
+ * OUTPUT point The new position
+ *************************************************************************/
+void rotate(Point & point, const Point & origin, int rotation)
+{
+ // because sine and cosine are expensive, we want to call them only once
+ double cosA = cos(deg2rad(rotation));
+ double sinA = sin(deg2rad(rotation));
+
+ // remember our original point
+ Point tmp(false /*check*/);
+ tmp.setX(point.getX() - origin.getX());
+ tmp.setY(point.getY() - origin.getY());
+
+ // find the new values
+ point.setX(static_cast<int> (tmp.getX() * cosA -
+ tmp.getY() * sinA) +
+ origin.getX());
+ point.setY(static_cast<int> (tmp.getX() * sinA +
+ tmp.getY() * cosA) +
+ origin.getY());
+}
+
+/************************************************************************
+ * DRAW LINE
+ * Draw a line on the screen from the beginning to the end.
+ * INPUT begin The position of the beginning of the line
+ * end The position of the end of the line
+ *************************************************************************/
+void drawLine(const Point & begin, const Point & end,
+ float red, float green, float blue)
+{
+ // Get ready...
+ glBegin(GL_LINES);
+ glColor3f(red, green, blue);
+
+ // Draw the actual line
+ glVertex2f(begin.getX(), begin.getY());
+ glVertex2f( end.getX(), end.getY());
+
+ // Complete drawing
+ glColor3f(1.0 /* red % */, 1.0 /* green % */, 1.0 /* blue % */);
+ glEnd();
+}
+
+/***********************************************************************
+ * DRAW Lander
+ * Draw a moon-lander spaceship on the screen at a given point
+ ***********************************************************************/
+void drawLander(const Point & point)
+{
+ // ultra simple point
+ struct PT
+ {
+ int x;
+ int y;
+ } points[] =
+ {
+ {-6, 0}, {-10,0}, {-8, 0}, {-8, 3}, // left foot
+ {-5, 4}, {-5, 7}, {-8, 3}, {-5, 4}, // left leg
+ {-1, 4}, {-3, 2}, { 3, 2}, { 1, 4}, {-1, 4}, // bottom
+ { 5, 4}, { 5, 7}, {-5, 7}, {-3, 7}, // engine square
+ {-6,10}, {-6,13}, {-3,16}, { 3,16}, // left of habitat
+ { 6,13}, { 6,10}, { 3, 7}, { 5, 7}, // right of habitat
+ { 5, 4}, { 8, 3}, { 5, 7}, { 5, 4}, // right leg
+ { 8, 3}, { 8, 0}, {10, 0}, { 6, 0} // right foot
+ };
+
+ // draw it
+ glBegin(GL_LINE_STRIP);
+ for (int i = 0; i < sizeof(points) / sizeof(points[0]); i++)
+ glVertex2f(point.getX() + points[i].x,
+ point.getY() + points[i].y);
+
+ // complete drawing
+ glEnd();
+
+
+}
+
+
+/***********************************************************************
+ * DRAW Lander Flame
+ * Draw the flames coming out of a moonlander for thrust
+ ***********************************************************************/
+void drawLanderFlames(const Point & point,
+ bool bottom,
+ bool left,
+ bool right)
+{
+ // simple point
+ struct PT
+ {
+ int x;
+ int y;
+ };
+
+ int iFlame = random(0, 3); // so the flame flickers
+
+ // draw it
+ glBegin(GL_LINE_LOOP);
+ glColor3f(1.0 /* red % */, 0.0 /* green % */, 0.0 /* blue % */);
+
+ // bottom thrust
+ if (bottom)
+ {
+ PT points[3][3] =
+ {
+ { {-5, -6}, { 0, -1}, { 3, -10} },
+ { {-3, -6}, {-1, -2}, { 0, -15} },
+ { { 2, -12}, { 1, 0}, { 6, -4} }
+ };
+
+ glVertex2f(point.getX() - 2, point.getY() + 2);
+ for (int i = 0; i < 3; i++)
+ glVertex2f(point.getX() + points[iFlame][i].x,
+ point.getY() + points[iFlame][i].y);
+ glVertex2f(point.getX() + 2, point.getY() + 2);
+ }
+
+ // right thrust
+ if (right)
+ {
+ PT points[3][3] =
+ {
+ { {10, 14}, { 8, 12}, {12, 12} },
+ { {12, 10}, { 8, 10}, {10, 8} },
+ { {14, 11}, {14, 11}, {14, 11} }
+ };
+
+ glVertex2f(point.getX() + 6, point.getY() + 12);
+ for (int i = 0; i < 3; i++)
+ glVertex2f(point.getX() + points[iFlame][i].x,
+ point.getY() + points[iFlame][i].y);
+ glVertex2f(point.getX() + 6, point.getY() + 10);
+ }
+
+ // left thrust
+ if (left)
+ {
+ PT points[3][3] =
+ {
+ { {-10, 14}, { -8, 12}, {-12, 12} },
+ { {-12, 10}, { -8, 10}, {-10, 8} },
+ { {-14, 11}, {-14, 11}, {-14, 11} }
+ };
+
+ glVertex2f(point.getX() - 6, point.getY() + 12);
+ for (int i = 0; i < 3; i++)
+ glVertex2f(point.getX() + points[iFlame][i].x,
+ point.getY() + points[iFlame][i].y);
+ glVertex2f(point.getX() - 6, point.getY() + 10);
+ }
+
+ glColor3f(1.0 /* red % */, 1.0 /* green % */, 1.0 /* blue % */);
+ glEnd();
+}
+
+
+/******************************************************************
+ * RANDOM
+ * This function generates a random number.
+ *
+ * INPUT: min, max : The number of values (min <= num <= max)
+ * OUTPUT <return> : Return the integer
+ ****************************************************************/
+int random(int min, int max)
+{
+ assert(min < max);
+ int num = (rand() % (max - min)) + min;
+ assert(min <= num && num <= max);
+
+ return num;
+}
+
+/******************************************************************
+ * RANDOM
+ * This function generates a random number.
+ *
+ * INPUT: min, max : The number of values (min <= num <= max)
+ * OUTPUT <return> : Return the double
+ ****************************************************************/
+double random(double min, double max)
+{
+ assert(min <= max);
+ double num = min + ((double)rand() / (double)RAND_MAX * (max - min));
+
+ assert(min <= num && num <= max);
+
+ return num;
+}
+
+
+/************************************************************************
+ * DRAW RECTANGLE
+ * Draw a rectangle on the screen centered on a given point (center) of
+ * a given size (width, height), and at a given orientation (rotation)
+ * INPUT center Center of the rectangle
+ * width Horizontal size
+ * height Vertical size
+ * rotation Orientation
+ *************************************************************************/
+void drawRect(const Point & center, int width, int height, int rotation)
+{
+ Point tl(false /*check*/); // top left
+ Point tr(false /*check*/); // top right
+ Point bl(false /*check*/); // bottom left
+ Point br(false /*check*/); // bottom right
+
+ //Top Left point
+ tl.setX(center.getX() - (width / 2));
+ tl.setY(center.getY() + (height / 2));
+
+ //Top right point
+ tr.setX(center.getX() + (width / 2));
+ tr.setY(center.getY() + (height / 2));
+
+ //Bottom left point
+ bl.setX(center.getX() - (width / 2));
+ bl.setY(center.getY() - (height / 2));
+
+ //Bottom right point
+ br.setX(center.getX() + (width / 2));
+ br.setY(center.getY() - (height / 2));
+
+ //Rotate all points the given degrees
+ rotate(tl, center, rotation);
+ rotate(tr, center, rotation);
+ rotate(bl, center, rotation);
+ rotate(br, center, rotation);
+
+ //Finally draw the rectangle
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(tl.getX(), tl.getY());
+ glVertex2f(tr.getX(), tr.getY());
+ glVertex2f(br.getX(), br.getY());
+ glVertex2f(bl.getX(), bl.getY());
+ glVertex2f(tl.getX(), tl.getY());
+ glEnd();
+}
+
+/************************************************************************
+ * DRAW CIRCLE
+ * Draw a circle from a given location (center) of a given size (radius).
+ * INPUT center Center of the circle
+ * radius Size of the circle
+ *************************************************************************/
+void drawCircle(const Point & center, int radius)
+{
+ assert(radius > 1.0);
+ const double increment = 1.0 / (double)radius;
+
+ // begin drawing
+ glBegin(GL_LINE_LOOP);
+
+ // go around the circle
+ for (double radians = 0; radians < M_PI * 2.0; radians += increment)
+ glVertex2f(center.getX() + (radius * cos(radians)),
+ center.getY() + (radius * sin(radians)));
+
+ // complete drawing
+ glEnd();
+}
+
+/************************************************************************
+ * DRAW DOT
+ * Draw a single point on the screen, 2 pixels by 2 pixels
+ * INPUT point The position of the dow
+ *************************************************************************/
+void drawDot(const Point & point)
+{
+ // Get ready, get set...
+ glBegin(GL_POINTS);
+
+ // Go...
+ glVertex2f(point.getX(), point.getY() );
+ glVertex2f(point.getX() + 1, point.getY() );
+ glVertex2f(point.getX() + 1, point.getY() + 1);
+ glVertex2f(point.getX(), point.getY() + 1);
+
+ // Done! OK, that was a bit too dramatic
+ glEnd();
+}
+
+/************************************************************************
+ * DRAW Tough Bird
+ * Draw a tough bird on the screen
+ * INPUT point The position of the sacred
+ * radius The size of the bird
+ * hits How many its remaining to kill the bird
+ *************************************************************************/
+void drawToughBird(const Point & center, float radius, int hits)
+{
+ assert(radius > 1.0);
+ const double increment = M_PI / 6.0;
+
+ // begin drawing
+ glBegin(GL_TRIANGLES);
+
+ // three points: center, pt1, pt2
+ Point pt1(false /*check*/);
+ pt1.setX(center.getX() + (radius * cos(0.0)));
+ pt1.setY(center.getY() + (radius * sin(0.0)));
+ Point pt2(pt1);
+
+ // go around the circle
+ for (double radians = increment;
+ radians <= M_PI * 2.0 + .5;
+ radians += increment)
+ {
+ pt2.setX(center.getX() + (radius * cos(radians)));
+ pt2.setY(center.getY() + (radius * sin(radians)));
+
+ glVertex2f(center.getX(), center.getY());
+ glVertex2f(pt1.getX(), pt1.getY() );
+ glVertex2f(pt2.getX(), pt2.getY() );
+
+ pt1 = pt2;
+ }
+
+ // complete drawing
+ glEnd();
+
+ // draw the score in the center
+ if (hits > 0 && hits < 10)
+ {
+ glColor3f(0.0 /* red % */, 0.0 /* green % */, 0.0 /* blue % */);
+ glRasterPos2f(center.getX() - 4, center.getY() - 3);
+ glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (char)(hits + '0'));
+ glColor3f(1.0, 1.0, 1.0); // reset to white
+ }
+}
+
+/************************************************************************
+ * DRAW Sacred Bird
+ * Draw a sacred bird on the screen
+ * INPUT point The position of the sacred
+ * radius The size of the bird
+ *************************************************************************/
+void drawSacredBird(const Point & center, float radius)
+{
+ // handle auto-rotation
+ static float rotation = 0.0;
+ rotation += 5.0;
+
+
+ // begin drawing
+ glBegin(GL_LINE_LOOP);
+ glColor3f(1.0 /* red % */, 0.0 /* green % */, 0.0 /* blue % */);
+
+
+ //loop around a circle the given number of times drawing a line from
+ //one point to the next
+ for (int i = 0; i < 5; i++)
+ {
+ Point temp(false /*check*/);
+ float radian = (float)i * (M_PI * 2.0) * 0.4;
+ temp.setX(center.getX() + (radius * cos(radian)));
+ temp.setY(center.getY() + (radius * sin(radian)));
+ rotate(temp, center, rotation);
+ glVertex2f(temp.getX(), temp.getY());
+ }
+
+ // complete drawing
+ glColor3f(1.0, 1.0, 1.0); // reset to white
+ glEnd();
+}
+
+/**********************************************************************
+ * DRAW SMALL ASTEROID
+ **********************************************************************/
+void drawSmallAsteroid( const Point & center, int rotation)
+{
+ // ultra simple point
+ struct PT
+ {
+ int x;
+ int y;
+ } points[] =
+ {
+ {-5, 9}, {4, 8}, {8, 4},
+ {8, -5}, {-2, -8}, {-2, -3},
+ {-8, -4}, {-8, 4}, {-5, 10}
+ };
+
+ glBegin(GL_LINE_STRIP);
+ glColor3f(1.0 /* red % */, 0.0/* green % */, 1.0/* blue % */);
+ for (int i = 0; i < sizeof(points)/sizeof(PT); i++)
+ {
+ Point pt(center.getX() + points[i].x,
+ center.getY() + points[i].y);
+ rotate(pt, center, rotation);
+ glVertex2f(pt.getX(), pt.getY());
+ }
+ glEnd();
+}
+
+/**********************************************************************
+ * DRAW MEDIUM ASTEROID
+ **********************************************************************/
+void drawMediumAsteroid( const Point & center, int rotation)
+{
+ // ultra simple point
+ struct PT
+ {
+ int x;
+ int y;
+ } points[] =
+ {
+ {2, 8}, {8, 15}, {12, 8},
+ {6, 2}, {12, -6}, {2, -15},
+ {-6, -15}, {-14, -10}, {-15, 0},
+ {-4, 15}, {2, 8}
+ };
+
+ glBegin(GL_LINE_STRIP);
+ glColor3f(1.0 /* red % */, 0.0/* green % */, 1.0/* blue % */);
+ for (int i = 0; i < sizeof(points)/sizeof(PT); i++)
+ {
+ Point pt(center.getX() + points[i].x,
+ center.getY() + points[i].y);
+ rotate(pt, center, rotation);
+ glVertex2f(pt.getX(), pt.getY());
+ }
+ glEnd();
+}
+
+/**********************************************************************
+ * DRAW LARGE ASTEROID
+ **********************************************************************/
+void drawLargeAsteroid( const Point & center, int rotation)
+{
+ // ultra simple point
+ struct PT
+ {
+ int x;
+ int y;
+ } points[] =
+ {
+ {0, 12}, {8, 20}, {16, 14},
+ {10, 12}, {20, 0}, {0, -20},
+ {-18, -10}, {-20, -2}, {-20, 14},
+ {-10, 20}, {0, 12}
+ };
+
+ glBegin(GL_LINE_STRIP);
+ glColor3f(1.0 /* red % */, 0.0/* green % */, 0.0/* blue % */);
+ for (int i = 0; i < sizeof(points)/sizeof(PT); i++)
+ {
+ Point pt(center.getX() + points[i].x,
+ center.getY() + points[i].y);
+ rotate(pt, center, rotation);
+ glVertex2f(pt.getX(), pt.getY());
+ }
+ glEnd();
+}
+
+
+/************************************************************************
+ * DRAW Ship
+ * Draw a spaceship on the screen
+ * INPUT point The position of the ship
+ * angle Which direction it is ponted
+ *************************************************************************/
+void drawShip(const Point & center, int rotation, bool thrust)
+{
+ // ultra simple point
+ struct PT
+ {
+ int x;
+ int y;
+ };
+
+ // draw the ship
+ const PT pointsShip[] =
+ { // top r.wing r.engine l.engine l.wing top
+ {0, 6}, {6, -6}, {2, -3}, {-2, -3}, {-6, -6}, {0, 6}
+ };
+
+ glBegin(GL_LINE_STRIP);
+ glColor3f(0.0 /* red % */, 0.0/* green % */, 1.0/* blue % */);
+ for (int i = 0; i < sizeof(pointsShip)/sizeof(PT); i++)
+ {
+ Point pt(center.getX() + pointsShip[i].x,
+ center.getY() + pointsShip[i].y);
+ rotate(pt, center, rotation);
+ glVertex2f(pt.getX(), pt.getY());
+ }
+ glEnd();
+
+ // draw the flame if necessary
+ if (thrust)
+ {
+ const PT pointsFlame[3][5] =
+ {
+ { {-2, -3}, {-2, -13}, { 0, -6}, { 2, -13}, {2, -3} },
+ { {-2, -3}, {-4, -9}, {-1, -7}, { 1, -14}, {2, -3} },
+ { {-2, -3}, {-1, -14}, { 1, -7}, { 4, -9}, {2, -3} }
+ };
+
+ glBegin(GL_LINE_STRIP);
+ glColor3f(1.0 /* red % */, 0.0 /* green % */, 0.0 /* blue % */);
+ int iFlame = random(0, 3);
+ for (int i = 0; i < 5; i++)
+ {
+ Point pt(center.getX() + pointsFlame[iFlame][i].x,
+ center.getY() + pointsFlame[iFlame][i].y);
+ rotate(pt, center, rotation);
+ glVertex2f(pt.getX(), pt.getY());
+ }
+ glColor3f(1.0, 1.0, 1.0); // reset to white
+ glEnd();
+ }
+}
diff --git a/uiDraw.h b/uiDraw.h
new file mode 100644
index 0000000..caa0fb5
--- /dev/null
+++ b/uiDraw.h
@@ -0,0 +1,135 @@
+/***********************************************************************
+ * Header File:
+ * User Interface Draw : put pixels on the screen
+ * Author:
+ * Br. Helfrich
+ * Summary:
+ * This is the code necessary to draw on the screen. We have a collection
+ * of procedural functions here because each draw function does not
+ * retain state. In other words, they are verbs (functions), not nouns
+ * (variables) or a mixture (objects)
+ ************************************************************************/
+
+#ifndef UI_DRAW_H
+#define UI_DRAW_H
+
+#include <string> // To display text on the screen
+#include <cmath> // for M_PI, sin() and cos()
+#include "point.h" // Where things are drawn
+using std::string;
+
+/************************************************************************
+ * DRAW DIGIT
+ * Draw a single digit in the old school line drawing style. The
+ * size of the glyph is 8x11 or x+(0..7), y+(0..10)
+ *************************************************************************/
+void drawDigit(const Point & topLeft, char digit);
+
+/*************************************************************************
+ * DRAW NUMBER
+ * Display an integer on the screen using the 7-segment method
+ *************************************************************************/
+void drawNumber(const Point & topLeft, int number);
+
+/*************************************************************************
+ * DRAW TEXT
+ * Draw text using a simple bitmap font
+ ************************************************************************/
+void drawText(const Point & topLeft, const char * text);
+
+/************************************************************************
+ * ROTATE
+ * Rotate a given point (point) around a given origin (center) by a given
+ * number of degrees (angle).
+ *************************************************************************/
+void rotate(Point & point, const Point & origin, int rotation = 0);
+
+/************************************************************************
+ * DRAW RECTANGLE
+ * Draw a rectangle on the screen centered on a given point (center) of
+ * a given size (width, height), and at a given orientation (rotation)
+ * measured in degrees (0 - 360)
+ *************************************************************************/
+void drawRect(const Point & center, int width, int height, int rotation);
+
+/************************************************************************
+ * DRAW CIRCLE
+ * Draw a circle from a given location (center) of a given size (radius).
+ *************************************************************************/
+void drawCircle(const Point & center, int radius);
+
+/************************************************************************
+ * DRAW POLYGON
+ * Draw a polygon from a given location (center) of a given size (radius).
+ *************************************************************************/
+void drawPolygon(const Point & center,
+ int radius = 20,
+ int points = 4,
+ int rotation = 0);
+
+/************************************************************************
+ * DRAW LINE
+ * Draw a line on the screen from the beginning to the end.
+ *************************************************************************/
+void drawLine(const Point & begin, const Point & end,
+ float red = 1.0, float green = 1.0, float blue = 1.0);
+
+
+/***********************************************************************
+ * DRAW Lander
+ * Draw a moon-lander spaceship on the screen at a given point
+ ***********************************************************************/
+void drawLander(const Point & point);
+
+/***********************************************************************
+ * DRAW Lander Flame
+ * Draw the flames coming out of a moonlander for thrust
+ ***********************************************************************/
+void drawLanderFlames(const Point & point,
+ bool bottom,
+ bool left,
+ bool right);
+
+/************************************************************************
+ * DRAW DOT
+ * Draw a single point on the screen, 2 pixels by 2 pixels
+ *************************************************************************/
+void drawDot(const Point & point);
+
+/************************************************************************
+ * DRAW Sacred Bird
+ * Draw the bird on the screen
+ *************************************************************************/
+void drawSacredBird(const Point & center, float radius);
+
+/************************************************************************
+ * DRAW Tough Bird
+ * Draw a tough bird on the screen
+ *************************************************************************/
+void drawToughBird(const Point & center, float radius, int hits);
+
+/************************************************************************
+ * DRAW Ship
+ * Draw the spaceship on the screen
+ *************************************************************************/
+void drawShip(const Point & point, int rotation, bool thrust);
+
+/**********************************************************************
+ * DRAW * ASTEROID
+ **********************************************************************/
+void drawSmallAsteroid( const Point & point, int rotation);
+void drawMediumAsteroid(const Point & point, int rotation);
+void drawLargeAsteroid( const Point & point, int rotation);
+
+/******************************************************************
+ * RANDOM
+ * This function generates a random number. The user specifies
+ * The parameters
+ * INPUT: min, max : The number of values (min <= num <= max)
+ * OUTPUT <return> : Return the integer
+ ****************************************************************/
+int random(int min, int max);
+double random(double min, double max);
+
+
+#endif // UI_DRAW_H
diff --git a/uiInteract.cpp b/uiInteract.cpp
new file mode 100644
index 0000000..1e89833
--- /dev/null
+++ b/uiInteract.cpp
@@ -0,0 +1,326 @@
+/***********************************************************************
+ * Source File:
+ * UI INTERACT
+ * Author:
+ * Br. Helfrich
+ * Description:
+ * Implement the interfaces specified in uiInterface.h. This handles
+ * all the interfaces and events necessary to work with OpenGL. Your
+ * program will interface with this thorough the callback function
+ * pointer towards the bottom of the file.
+ ************************************************************************/
+
+#include <string> // need you ask?
+#include <sstream> // convert an integer into text
+#include <cassert> // I feel the need... the need for asserts
+#include <time.h> // for clock
+#include <cstdlib> // for rand()
+
+
+#ifdef __APPLE__
+#include <openGL/gl.h> // Main OpenGL library
+#include <GLUT/glut.h> // Second OpenGL library
+#endif // __APPLE__
+
+#ifdef __linux__
+#include <GL/gl.h> // Main OpenGL library
+#include <GL/glut.h> // Second OpenGL library
+#endif // __linux__
+
+#ifdef _WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#include <Gl/glut.h> // OpenGL library we copied
+#include <ctime> // for ::Sleep();
+#include <Windows.h>
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+#endif // _WIN32
+
+#include "uiInteract.h"
+#include "point.h"
+
+using namespace std;
+
+
+/*********************************************************************
+ * SLEEP
+ * Pause for a while. We want to put the program to sleep until it
+ * is time to draw again. Note that this requires us to tell the OS
+ * that we are idle. the nanosleep function performs this task for us
+ * INPUT: msSleep: sleep time in milliseconds
+ *********************************************************************/
+void sleep(unsigned long msSleep)
+{
+ // Windows handles sleep one way
+#ifdef _WIN32
+ ::Sleep(msSleep + 35);
+
+ // Unix-based operating systems (OS-X, Linux) do it another
+#else // LINUX, XCODE
+ timespec req = {};
+ time_t sec = (int)(msSleep / 1000);
+ msSleep -= (sec * 1000);
+
+ req.tv_sec = sec;
+ req.tv_nsec = msSleep * 1000000L;
+
+ while (nanosleep(&req, &req) == -1)
+ ;
+#endif // LINUX, XCODE
+ return;
+}
+
+/************************************************************************
+ * DRAW CALLBACK
+ * This is the main callback from OpenGL. It gets called constantly by
+ * the graphics engine to refresh and draw the window. Here we will
+ * clear the background buffer, draw on it, and send it to the forefront
+ * when the appropriate time period has passsed.
+ *
+ * Note: This and all other callbacks can't be member functions, they must
+ * have global scope for OpenGL to see them.
+ *************************************************************************/
+void drawCallback()
+{
+ // even though this is a local variable, all the members are static
+ Interface ui;
+ // Prepare the background buffer for drawing
+ glClear(GL_COLOR_BUFFER_BIT); //clear the screen
+ glColor3f(1,1,1);
+
+ //calls the client's display function
+ assert(ui.callBack != NULL);
+ ui.callBack(&ui, ui.p);
+
+ //loop until the timer runs out
+ if (!ui.isTimeToDraw())
+ sleep((unsigned long)((ui.getNextTick() - clock()) / 1000));
+
+ // from this point, set the next draw time
+ ui.setNextDrawTime();
+
+ // bring forth the background buffer
+ glutSwapBuffers();
+
+ // clear the space at the end
+ ui.keyEvent();
+}
+
+/************************************************************************
+ * KEY DOWN CALLBACK
+ * When a key on the keyboard has been pressed, we need to pass that
+ * on to the client. Currently, we are only registering the arrow keys
+ * INPUT key: the key we pressed according to the GLUT_KEY_ prefix
+ * x y: the position in the window, which we ignore
+ *************************************************************************/
+void keyDownCallback(int key, int x, int y)
+{
+ // Even though this is a local variable, all the members are static
+ // so we are actually getting the same version as in the constructor.
+ Interface ui;
+ ui.keyEvent(key, true /*fDown*/);
+}
+
+/************************************************************************
+ * KEY UP CALLBACK
+ * When the user has released the key, we need to reset the pressed flag
+ * INPUT key: the key we pressed according to the GLUT_KEY_ prefix
+ * x y: the position in the window, which we ignore
+ *************************************************************************/
+void keyUpCallback(int key, int x, int y)
+{
+ // Even though this is a local variable, all the members are static
+ // so we are actually getting the same version as in the constructor.
+ Interface ui;
+ ui.keyEvent(key, false /*fDown*/);
+}
+
+/***************************************************************
+ * KEYBOARD CALLBACK
+ * Generic callback to a regular ascii keyboard event, such as
+ * the space bar or the letter 'q'
+ ***************************************************************/
+void keyboardCallback(unsigned char key, int x, int y)
+{
+ // Even though this is a local variable, all the members are static
+ // so we are actually getting the same version as in the constructor.
+ Interface ui;
+ ui.keyEvent(key, true /*fDown*/);
+}
+
+/***************************************************************
+ * INTERFACE : KEY EVENT
+ * Either set the up or down event for a given key
+ * INPUT key which key is pressed
+ * fDown down or brown
+ ****************************************************************/
+void Interface::keyEvent(int key, bool fDown)
+{
+ switch(key)
+ {
+ case GLUT_KEY_DOWN:
+ isDownPress = fDown;
+ break;
+ case GLUT_KEY_UP:
+ isUpPress = fDown;
+ break;
+ case GLUT_KEY_RIGHT:
+ isRightPress = fDown;
+ break;
+ case GLUT_KEY_LEFT:
+ isLeftPress = fDown;
+ break;
+ case GLUT_KEY_HOME:
+ case ' ':
+ isSpacePress = fDown;
+ break;
+ }
+}
+/***************************************************************
+ * INTERFACE : KEY EVENT
+ * Either set the up or down event for a given key
+ * INPUT key which key is pressed
+ * fDown down or brown
+ ****************************************************************/
+void Interface::keyEvent()
+{
+ if (isDownPress)
+ isDownPress++;
+ if (isUpPress)
+ isUpPress++;
+ if (isLeftPress)
+ isLeftPress++;
+ if (isRightPress)
+ isRightPress++;
+ isSpacePress = false;
+}
+
+
+/************************************************************************
+ * INTEFACE : IS TIME TO DRAW
+ * Have we waited long enough to draw swap the background buffer with
+ * the foreground buffer?
+ *************************************************************************/
+bool Interface::isTimeToDraw()
+{
+ return ((unsigned int)clock() >= nextTick);
+}
+
+/************************************************************************
+ * INTERFACE : SET NEXT DRAW TIME
+ * What time should we draw the buffer again? This is a function of
+ * the current time and the frames per second.
+ *************************************************************************/
+void Interface::setNextDrawTime()
+{
+ nextTick = clock() + static_cast<int> (timePeriod * CLOCKS_PER_SEC);
+}
+
+/************************************************************************
+ * INTERFACE : SET FRAMES PER SECOND
+ * The frames per second dictates the speed of the game. The more frames
+ * per second, the quicker the game will appear to the user. We will default
+ * to 30 frames/second but the client can set this at will.
+ * INPUT value The number of frames per second. 30 is default
+ *************************************************************************/
+void Interface::setFramesPerSecond(double value)
+{
+ timePeriod = (1 / value);
+}
+
+/***************************************************
+ * STATICS
+ * All the static member variables need to be initialized
+ * Somewhere globally. This is a good spot
+ **************************************************/
+int Interface::isDownPress = 0;
+int Interface::isUpPress = 0;
+int Interface::isLeftPress = 0;
+int Interface::isRightPress = 0;
+bool Interface::isSpacePress = false;
+bool Interface::initialized = false;
+double Interface::timePeriod = 1.0 / 30; // default to 30 frames/second
+unsigned int Interface::nextTick = 0; // redraw now please
+void * Interface::p = NULL;
+void (*Interface::callBack)(const Interface *, void *) = NULL;
+
+
+/************************************************************************
+ * INTERFACE : DESTRUCTOR
+ * Nothing here!
+ ***********************************************************************/
+Interface::~Interface()
+{
+}
+
+
+/************************************************************************
+ * INTEFACE : INITIALIZE
+ * Initialize our drawing window. This will set the size and position,
+ * get ready for drawing, set up the colors, and everything else ready to
+ * draw the window. All these are part of initializing Open GL.
+ * INPUT argc: Count of command-line arguments from main
+ * argv: The actual command-line parameters
+ * title: The text for the titlebar of the window
+ *************************************************************************/
+void Interface::initialize(int argc, char ** argv, const char * title, Point topLeft, Point bottomRight)
+{
+ if (initialized)
+ return;
+
+ // set up the random number generator
+ srand((unsigned int)time(NULL));
+
+ // create the window
+ glutInit(&argc, argv);
+ Point point;
+ glutInitWindowSize( // size of the window
+ (int)(bottomRight.getX() - topLeft.getX()),
+ (int)(topLeft.getY() - bottomRight.getY()));
+
+ glutInitWindowPosition( 10, 10); // initial position
+ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // double buffering
+ glutCreateWindow(title); // text on titlebar
+ glutIgnoreKeyRepeat(true);
+
+ // set up the drawing style: B/W and 2D
+ glClearColor(0, 0, 0, 0); // Black is the background color
+ gluOrtho2D((int)topLeft.getX(), (int)bottomRight.getX(),
+ (int)bottomRight.getY(), (int)topLeft.getY()); // 2D environment
+
+ // register the callbacks so OpenGL knows how to call us
+ glutDisplayFunc( drawCallback );
+ glutIdleFunc( drawCallback );
+ glutKeyboardFunc( keyboardCallback);
+ glutSpecialFunc( keyDownCallback );
+ glutSpecialUpFunc( keyUpCallback );
+ initialized = true;
+
+ // done
+ return;
+}
+
+/************************************************************************
+ * INTERFACE : RUN
+ * Start the main graphics loop and play the game
+ * INPUT callBack: Callback function. Every time we are beginning
+ * to draw a new frame, we first callback to the client
+ * to see if he wants to do anything, such as move
+ * the game pieces or respond to input
+ * p: Void point to whatever the caller wants. You
+ * will need to cast this back to your own data
+ * type before using it.
+ *************************************************************************/
+void Interface::run(void (*callBack)(const Interface *, void *), void *p)
+{
+ // setup the callbacks
+ this->p = p;
+ this->callBack = callBack;
+
+ glutMainLoop();
+
+ return;
+}
+
diff --git a/uiInteract.h b/uiInteract.h
new file mode 100644
index 0000000..d7bfe6b
--- /dev/null
+++ b/uiInteract.h
@@ -0,0 +1,131 @@
+/*********************************************
+ * Header file:
+ * UI INTERFACE
+ * Author:
+ * Br. Helfrich
+ * Summary:
+ * This module will create an OpenGL window,
+ * enter the OpenGL main loop, and accept events.
+ * The main methods are:
+ * 1. Constructors - Create the window
+ * 2. run() - Run the main loop
+ * 3. callback - Specified in Run, this user-provided
+ * function will get called with every frame
+ * 4. isDown() - Is a given key pressed on this loop?
+ **********************************************/
+
+#ifndef UI_INTERFACE_H
+#define UI_INTERFACE_H
+
+ #include "point.h"
+
+/********************************************
+ * INTERFACE
+ * All the data necessary to keep our graphics
+ * state in memory
+ ********************************************/
+class Interface
+{
+public:
+ // Default constructor useful for setting up the random variables
+ // or for opening the file for output
+ Interface() { initialize(0, 0x0000, "Window", Point(-50, 50), Point(50, -50)); };
+
+ // Constructor if you want to set up the window with anything but
+ // the default parameters
+ Interface(int argc, char ** argv, const char * title, Point topLeft, Point bottomRight)
+ {
+ initialize(argc, argv, title, topLeft, bottomRight);
+ }
+
+ // Destructor, incase any housecleaning needs to occr
+ ~Interface();
+
+ // This will set the game in motion
+ void run(void (*callBack)(const Interface *, void *), void *p);
+
+ // Is it time to redraw the screen
+ bool isTimeToDraw();
+
+ // Set the next draw time based on current time and time period
+ void setNextDrawTime();
+
+ // Retrieve the next tick time... the time of the next draw.
+ unsigned int getNextTick() { return nextTick; };
+
+ // How many frames per second are we configured for?
+ void setFramesPerSecond(double value);
+
+ // Key event indicating a key has been pressed or not. The callbacks
+ // should be the only onces to call this
+ void keyEvent(int key, bool fDown);
+ void keyEvent();
+
+ // Current frame rate
+ double frameRate() const { return timePeriod; };
+
+ // Get various key events
+ int isDown() const { return isDownPress; };
+ int isUp() const { return isUpPress; };
+ int isLeft() const { return isLeftPress; };
+ int isRight() const { return isRightPress; };
+ bool isSpace() const { return isSpacePress; };
+
+ static void *p; // for client
+ static void (*callBack)(const Interface *, void *);
+
+private:
+ void initialize(int argc, char ** argv, const char * title, Point topLeft, Point bottomRight);
+
+ static bool initialized; // only run the constructor once!
+ static double timePeriod; // interval between frame draws
+ static unsigned int nextTick; // time (from clock()) of our next draw
+
+ static int isDownPress; // is the down arrow currently pressed?
+ static int isUpPress; // " up "
+ static int isLeftPress; // " left "
+ static int isRightPress; // " right "
+ static bool isSpacePress; // " space "
+};
+
+
+
+/************************************************************************
+ * DRAW CALLBACK
+ * This is the main callback from OpenGL. It gets called constantly by
+ * the graphics engine to refresh and draw the window. Here we will
+ * clear the background buffer, draw on it, and send it to the forefront
+ * when the appropriate time period has passsed.
+ *
+ * Note: This and all other callbacks can't be member functions, they must
+ * have global scope for OpenGL to see them.
+ *************************************************************************/
+void drawCallback();
+
+/************************************************************************
+ * KEY DOWN CALLBACK
+ * When a key on the keyboard has been pressed, we need to pass that
+ * on to the client. Currnetly, we are only registering the arrow keys
+ *************************************************************************/
+void keyDownCallback(int key, int x, int y);
+
+/************************************************************************
+ * KEY UP CALLBACK
+ * When the user has released the key, we need to reset the pressed flag
+ *************************************************************************/
+void keyUpCallback(int key, int x, int y);
+
+/***************************************************************
+ * KEYBOARD CALLBACK
+ * Generic callback to a regular ascii keyboard event, such as
+ * the space bar or the letter 'q'
+ ***************************************************************/
+void keyboardCallback(unsigned char key, int x, int y);
+
+/************************************************************************
+ * RUN
+ * Set the game in action. We will get control back in our drawCallback
+ *************************************************************************/
+void run();
+
+#endif // UI_INTERFACE_H
diff --git a/velocity.cpp b/velocity.cpp
new file mode 100644
index 0000000..ceca109
--- /dev/null
+++ b/velocity.cpp
@@ -0,0 +1,59 @@
+#include "velocity.h"
+
+// Default velocity constructor
+Velocity :: Velocity ()
+{
+ setDx ( 0.0 );
+ setDy ( 0.0 );
+}
+
+// Velocity constructor
+Velocity :: Velocity ( float dx , float dy )
+{
+ setDx ( dx );
+ setDy ( dy );
+}
+
+// Get Velocity dx
+float Velocity :: getDx() const
+{
+ return dx;
+}
+
+// Get Velocity dy
+float Velocity :: getDy() const
+{
+ return dy;
+}
+
+// Set Velocity dx
+void Velocity :: setDx( float dx )
+{
+ this->dx = dx;
+}
+
+// Set Velocity dy
+void Velocity :: setDy( float dy )
+{
+ this->dy = dy;
+}
+
+// Add dy Velocity
+void Velocity :: addDy ( const float dy )
+{
+ this->dy += dy;
+}
+
+// Add dx Velocity
+void Velocity :: addDx ( const float dx )
+{
+ this->dx += dx;
+}
+
+// Update a point
+Point Velocity :: updatePoint ( Point &point )
+{
+ point.addX ( dx );
+ point.addY ( dy );
+ return point;
+}
diff --git a/velocity.h b/velocity.h
new file mode 100644
index 0000000..11c41cb
--- /dev/null
+++ b/velocity.h
@@ -0,0 +1,23 @@
+#ifndef VELOCITY_H
+#define VELOCITY_H
+
+#include "point.h"
+
+class Velocity
+{
+ public:
+ Velocity();
+ Velocity( float dx , float dy );
+ float getDx() const;
+ float getDy() const;
+ void addDy( const float dy );
+ void addDx( const float dx );
+ void setDx( float dx );
+ void setDy( float dy );
+ Point updatePoint ( Point &point );
+ private:
+ float dx;
+ float dy;
+};
+
+#endif