Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed 4DGL-uLCD-SE PinDetect
main.cpp
- Committer:
- Nydrel
- Date:
- 2018-11-29
- Revision:
- 5:ed52ac77cdf9
- Parent:
- 4:d128df681d05
File content as of revision 5:ed52ac77cdf9:
#include "mbed.h"
#include "MMA8452.h"
#include "uLCD_4DGL.h"
#include "PinDetect.h"
#include "Speaker.h"
#include <ctime>
/*-----Define Statements-----*/
#define ASTEROID_HEIGHT 12
#define ASTEROID_WIDTH 15
#define SPRITE_MAX 15
#define EARTH_WIDTH 10
#define EARTH_HEIGHT 10
#define EXPLOSION1_WIDTH 20
#define SCREEN_MAX 125
#define SCREEN_MIN 1
#define NUM_ASTEROIDS 4
#define Q 0x808000 //OLIVE
#define I 0x008000 //GREEN
#define S 0xC0C0C0 //SILVER
#define C 0x17202A //UFO GLASS
#define D 0x797D7F //DARK GREY
#define L 0x00FF00 //LIME
#define P 0xFF00FF //PINK
#define R 0xF1C40F //YELLOW
#define O 0xF39C12 //ORANGE
#define G 0xAAB7B8 //GREY
#define _ 0x000000 //BLACK
#define X 0xFFFFFF //WHITE
#define B 0x0000FF //BLUE
#define r 0xFF0000 //RED
/*-----Sprites------*/
int spaceship_earth1[EARTH_WIDTH * EARTH_HEIGHT] =
{
_,_,S,S,S,S,S,S,_,_,
_,S,I,I,I,I,I,I,S,_,
S,I,I,I,I,I,I,I,I,S,
S,I,I,I,I,I,I,I,I,S,
S,I,I,I,I,I,I,I,I,S,
S,I,I,I,I,I,I,I,I,S,
S,I,I,I,I,I,I,I,I,S,
S,I,I,I,I,I,I,I,I,S,
S,I,I,I,I,I,I,I,S,_,
_,S,S,S,S,S,S,S,_,_
};
int earth_blank[EARTH_WIDTH * EARTH_HEIGHT] =
{
_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_
};
int earth_destroy[EARTH_WIDTH * EARTH_HEIGHT] =
{
R,R,R,R,R,R,R,R,R,R,
R,R,r,_,_,r,_,_,r,R,
R,R,_,r,_,r,_,r,_,R,
R,R,_,_,r,r,r,_,_,R,
R,R,r,r,r,r,r,r,r,R,
R,R,_,_,r,r,r,_,_,R,
R,R,_,r,_,r,_,r,_,R,
R,R,r,_,_,r,_,_,r,R,
R,R,R,R,R,R,R,R,R,R,
R,R,R,R,R,R,R,R,R,R
};
int asteroid_sprite_1[ASTEROID_HEIGHT * ASTEROID_WIDTH] = {
_,_,_,_,X,X,X,X,X,X,X,X,_,_,_,
_,_,_,X,_,_,_,_,_,_,_,_,X,_,_,
_,_,X,_,_,_,_,_,_,_,_,_,X,_,_,
_,X,_,_,_,_,_,_,_,_,_,_,X,_,_,
X,X,X,X,_,_,_,_,_,_,_,_,_,X,_,
_,_,_,X,_,_,_,_,_,_,_,_,_,X,_,
_,_,X,_,_,_,_,_,_,_,_,_,_,X,_,
_,X,_,_,_,_,_,X,_,_,_,_,_,X,_,
X,_,_,_,_,_,X,X,_,_,_,_,X,_,_,
_,X,_,_,_,X,_,X,_,_,_,_,X,_,_,
_,_,X,_,X,_,_,X,_,_,_,X,_,_,_,
_,_,_,X,_,_,_,X,X,X,X,_,_,_,_
};
int asteroid_sprite_2[ASTEROID_HEIGHT * ASTEROID_WIDTH] = {
_,_,X,X,X,X,X,X,X,X,_,_,_,_,_,
_,_,_,X,_,_,_,_,_,_,X,X,_,_,_,
_,_,_,_,X,_,_,_,_,_,_,_,X,_,_,
X,X,X,X,X,X,_,_,_,_,_,_,_,X,_,
X,_,_,_,_,_,_,_,_,_,_,_,_,_,X,
X,_,_,_,_,_,_,_,_,_,_,_,_,X,X,
X,_,_,_,_,_,_,_,_,_,_,X,X,_,_,
_,X,_,_,_,_,_,_,_,_,X,_,_,_,_,
_,_,X,_,_,_,_,_,_,_,_,X,X,_,_,
_,_,_,X,_,_,_,_,X,_,_,_,_,X,X,
_,_,_,_,X,_,X,X,_,X,X,_,_,X,_,
_,_,_,_,_,X,_,_,_,_,_,X,X,_,_
};
int asteroid_sprite_3[ASTEROID_HEIGHT * ASTEROID_WIDTH] = {
_,_,X,X,X,_,_,_,_,_,_,X,X,_,_,
_,X,_,_,_,X,X,_,_,_,X,_,_,X,_,
X,_,_,_,_,_,_,X,X,X,_,_,_,_,X,
_,X,_,_,_,_,_,_,_,_,_,_,_,X,_,
_,_,X,_,_,_,_,_,_,_,X,X,X,_,_,
_,_,_,X,_,_,_,_,_,_,X,X,_,_,_,
_,_,X,_,_,_,_,_,_,_,_,_,X,_,_,
_,X,_,_,_,_,_,_,_,_,_,_,_,X,_,
X,_,_,_,_,_,_,_,_,_,_,_,_,_,X,
_,X,_,_,_,X,X,X,_,_,_,_,_,X,_,
_,_,X,_,X,_,_,_,X,X,_,X,X,_,_,
_,_,_,X,_,_,_,_,_,_,X,X,X,_,_
};
int asteroid_sprite_4[ASTEROID_HEIGHT * ASTEROID_WIDTH] = {
_,_,_,X,X,_,_,_,_,_,X,_,_,_,_,
_,_,X,_,_,X,_,_,_,X,_,X,X,_,_,
_,X,_,_,_,_,X,_,X,_,_,_,_,X,_,
X,_,_,_,_,_,_,X,_,_,_,_,_,_,X,
X,_,_,_,_,_,_,_,_,_,_,_,_,X,_,
X,_,_,_,_,_,_,_,_,_,_,_,X,_,_,
X,_,_,_,_,_,_,_,_,_,_,_,_,X,_,
X,_,_,_,_,_,_,_,_,_,_,_,_,_,X,
X,_,_,_,_,_,_,_,_,_,_,_,_,X,_,
_,X,_,_,_,_,_,_,_,_,_,_,X,_,_,
_,_,X,_,_,_,_,_,_,_,_,X,_,_,_,
_,_,_,X,X,X,X,X,X,X,X,_,_,_,_
};
int asteroid_blank[ASTEROID_WIDTH * ASTEROID_HEIGHT] =
{
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,_,_,_,_,_,_
};
//Instantiate Accelerometer Object
Serial pc(USBTX,USBRX); //not used in this program
MMA8452 acc(p9, p10, 40000); //instantiate an acc object!
double x, y, z;
//Instantiate uLCD Object
DigitalOut myled(LED1);
uLCD_4DGL uLCD(p28, p27, p29); // create a global uLCD object
Speaker mySpeaker(p21);
//Setup pushbutton for bomb
PinDetect pb1(p16);
int factor = 50;
int offset = 63;
bool BombUsed = false;
bool ExplodeAllAsteroids = false;
void pb1_hit_callback (void)
{
if (!BombUsed )
{
ExplodeAllAsteroids = true;
BombUsed = true;
}
}
/*-----ScreenObject Class------*/
class ScreenObject
{
public:
//ScreenObject();
//setter functions
/*void setXPos(int x)
{
x_pos = x;
}
void setYPos(int y)
{
y_pos = y;
} */
//getter functions
// int getXPos();
// int getYPos();
//pure virtual
virtual void draw() = 0;
virtual void update() = 0;
virtual bool boundaryCheck() = 0;
virtual void reset() = 0;
friend bool overlap(ScreenObject & objectA, ScreenObject & objectB)
{
bool rangeX = (objectA.x_pos <= objectB.x_pos + 7) && (objectA.x_pos + 8 >= objectB.x_pos);
bool rangeY = (objectA.y_pos <= objectB.y_pos + 7) && (objectA.y_pos + 7 >= objectB.y_pos);
return (rangeX && rangeY);
}
//you put stuff in here!
protected:
int x_pos;
int y_pos;
};
/*-----SpaceShipEarth Class------*/
class SpaceShipEarth: public ScreenObject
{
public:
SpaceShipEarth() {
x_pos = 63;
y_pos = 63;
}
void draw() {
uLCD.BLIT(x_pos, y_pos, EARTH_WIDTH, EARTH_HEIGHT,spaceship_earth1);
}
void update() {
uLCD.BLIT(x_pos, y_pos, EARTH_WIDTH, EARTH_HEIGHT,earth_blank);
if(!acc.isXYZReady()) {
wait(0.02);
}
else {
acc.readXYZGravity(&x,&y,&z); //notice this is passed by reference use pointers
x_pos = -1*x*factor + offset;
y_pos = -1*y*factor + offset;
} //end else
}//end if
void explode() {
uLCD.BLIT(x_pos, y_pos, EARTH_WIDTH, EARTH_HEIGHT,earth_blank);
uLCD.BLIT(x_pos, y_pos, EARTH_WIDTH, EARTH_HEIGHT,earth_destroy);
}
bool boundaryCheck()
{
if(((x_pos == 0) || (x_pos == 126)) || ((y_pos == 0) || (y_pos == 126)))
return true;
else
return false;
}
void reset()
{
x_pos = 63;
y_pos = 63;
}
/*
bool boundaryCheck(* ScreenObject asteroid)
{
//compare the four corners of the Earth and asteroid sprites
bool c1 = (asteroid->x_pos) <=
}
*/
};
/*-----AbstractAsteroid Class-----*/
class AbstractAsteroid: public ScreenObject
{
public:
void pickCorner(int corner)
{
switch (corner)
{
case 1: //top left
x_pos = 2;
y_pos = 2;
deltaX = rand() % 3 + 1;
deltaY = rand() % 3 + 1;
break;
case 2: //top right
x_pos = 124 - ASTEROID_WIDTH;
y_pos = 2;
deltaX = -1*(rand() % 3 + 1);
deltaY = rand() % 3 + 1;
break;
case 3: //bottom left
x_pos = 2;
y_pos = 124 - ASTEROID_HEIGHT;
deltaX = rand() % 3 + 1;
deltaY = -1*(rand() % 3 + 1);
break;
case 4: //bottom right
x_pos = 124 - ASTEROID_WIDTH;
y_pos = 124 - ASTEROID_HEIGHT;
deltaX = -1*(rand() % 3 + 1);
deltaY = -1*(rand() % 3 + 1);
break;
}
}
void pickEdge()
{
int edge = rand() % 4 + 1;
switch (edge)
{
case 1: //top
x_pos = rand() % 2 + (120 - ASTEROID_WIDTH);
y_pos = 2;
if((rand() % 1))
deltaX = rand() % 3 + 1;
else
deltaX = -1*(rand() % 3 + 1);
deltaY = rand() % 3 + 1;
break;
case 2: //bottom
x_pos = rand() % 2 + (120 - ASTEROID_WIDTH);
y_pos = 120 - ASTEROID_HEIGHT;
if((rand() % 1))
deltaX = rand() % 3 + 1;
else
deltaX = -1*(rand() % 3 + 1);
deltaY = -1*(rand() % 3 + 1);
break;
case 3: //left
x_pos = 2;
y_pos = rand() % 1 + (120 - ASTEROID_HEIGHT);
deltaX = rand() % 3 + 1;
if((rand() % 1))
deltaY = rand() % 3 + 1;
else
deltaY = -1*(rand() % 3 + 1);
break;
case 4: //right
x_pos = 120 - ASTEROID_WIDTH;
y_pos = rand() % 1 + (120 - ASTEROID_HEIGHT);
deltaX = -1*(rand() % 3 + 1);
if((rand() % 1))
deltaY = rand() % 3 + 1;
else
deltaY = -1*(rand() % 3 + 1);
break;
}
}
bool boundaryCheck()
{
bool c1 = x_pos + ASTEROID_WIDTH > 124; //if moving towards right side of screen
bool c2 = x_pos <= 0; //if moving towards left side of screen
bool c3 = y_pos + ASTEROID_HEIGHT > 124; //if moving towards bottom of screen
bool c4 = y_pos <= 0; //if moving towards top of screen
if(c1 || c2 || c3 || c4)
return true;
else
return false;
}
protected:
int deltaX;
int deltaY;
};
//-----Concrete Asteroids-----//
//-----Asteroid1-----//
class Asteroid1: public AbstractAsteroid
{
public:
Asteroid1(int corner)
{
pickCorner(corner);
startTime = time(0);
}
void reset()
{
pickEdge();
startTime = time(0);
}
void draw()
{
uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_sprite_1);
}
void update()
{
uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_blank);
wait(0.02);
time_t timeElapsed = time(0)-startTime;
x_pos = x_pos + (deltaX * timeElapsed);
y_pos = y_pos + (deltaY * timeElapsed);
}
protected:
time_t startTime;
};
//-----Asteroid2-----//
class Asteroid2: public AbstractAsteroid
{
public:
Asteroid2(int corner)
{
pickCorner(corner);
startTime = time(0);
}
void reset()
{
pickEdge();
startTime = time(0);
}
void draw()
{
uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_sprite_2);
}
void update()
{
uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_blank);
wait(0.02);
time_t timeElapsed = time(0)-startTime;
x_pos = x_pos + (deltaX * timeElapsed);
y_pos = y_pos + (deltaY * timeElapsed);
}
protected:
time_t startTime;
};
//-----Asteroid3-----//
class Asteroid3: public AbstractAsteroid
{
public:
Asteroid3(int corner)
{
pickCorner(corner);
startTime = time(0);
}
void reset()
{
pickEdge();
startTime = time(0);
}
void draw()
{
uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_sprite_3);
}
void update()
{
uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_blank);
wait(0.02);
time_t timeElapsed = time(0)-startTime;
x_pos = x_pos + (deltaX * timeElapsed);
y_pos = y_pos + (deltaY * timeElapsed);
}
protected:
time_t startTime;
};
//-----Asteroid4-----//
class Asteroid4: public AbstractAsteroid
{
public:
Asteroid4(int corner)
{
pickCorner(corner);
startTime = time(0);
}
void reset()
{
pickEdge();
startTime = time(0);
}
void draw()
{
uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_sprite_4);
}
void update()
{
uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_blank);
wait(0.02);
time_t timeElapsed = time(0)-startTime;
x_pos = x_pos + (deltaX * timeElapsed);
y_pos = y_pos + (deltaY * timeElapsed);
}
protected:
time_t startTime;
};
//Program Start
int main()
{
uLCD.baudrate(300000);
wait(0.2);
srand(time(0)); // do this srand call here ONLY... no where else in the code!
ScreenObject * ActiveAsteroids[NUM_ASTEROIDS];
SpaceShipEarth ship; //instantiate a SpaceShipEarth object
pb1.mode(PullUp);
wait(0.01);
pb1.attach_deasserted(&pb1_hit_callback);
pb1.setSampleFrequency();
double bar = 127;
Asteroid1 rock1(1);
Asteroid2 rock2(2);
Asteroid3 rock3(3);
Asteroid4 rock4(4);
ActiveAsteroids[0] = &rock1;
ActiveAsteroids[1] = &rock2;
ActiveAsteroids[2] = &rock3;
ActiveAsteroids[3] = &rock4;
//set parameters -- use these and don't change
acc.setBitDepth(MMA8452::BIT_DEPTH_12);
acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_4G);
acc.setDataRate(MMA8452::RATE_100);
time_t startTime;
time_t timeElapsed;
startTime = time(0);
int dur = 30;
while(1) {
//check winning condition
if((time(0)-startTime) > dur)
{
uLCD.printf("YOU WIN!");
return 1;
}
else
{
timeElapsed = time(0)-startTime;
bar = 127 - (timeElapsed*(127/dur));
uLCD.filled_rectangle(1, 1,127,1,R);
uLCD.filled_rectangle(1, 1,127-bar,1,_);
}
ship.update();
ship.draw();
ActiveAsteroids[0]->update();
if(ActiveAsteroids[0]->boundaryCheck())
ActiveAsteroids[0]->reset();
ActiveAsteroids[0]->draw();
ActiveAsteroids[1]->update();
if(ActiveAsteroids[1]->boundaryCheck())
ActiveAsteroids[1]->reset();
ActiveAsteroids[1]->draw();
ActiveAsteroids[2]->update();
if(ActiveAsteroids[2]->boundaryCheck())
ActiveAsteroids[2]->reset();
ActiveAsteroids[2]->draw();
ActiveAsteroids[3]->update();
if(ActiveAsteroids[3]->boundaryCheck())
ActiveAsteroids[3]->reset();
ActiveAsteroids[3]->draw();
//check to see if the pushbutton has activated the bomb
if(ExplodeAllAsteroids)
{
for(int i = 0; i < 4; i++)
{
ActiveAsteroids[i]->update();
wait(0.25);
ActiveAsteroids[i]->reset();
}
ExplodeAllAsteroids = false;
}
//check for overlap between Asteroids and Earth
//return 1 and end game
if(overlap(ship,rock1)) {
ship.explode();
mySpeaker.PlayNote(500.0,0.25,0.1);
mySpeaker.PlayNote(450.0,0.25,0.1);
mySpeaker.PlayNote(400.0,0.25,0.1);
mySpeaker.PlayNote(300.0,0.25,0.1);
uLCD.printf("GAME OVER");
wait(3);
return 1;
}
else if(overlap(ship,rock2)) {
ship.explode();
mySpeaker.PlayNote(500.0,0.25,0.1);
mySpeaker.PlayNote(450.0,0.25,0.1);
mySpeaker.PlayNote(400.0,0.25,0.1);
mySpeaker.PlayNote(300.0,0.25,0.1);
uLCD.printf("GAME OVER");
wait(3);
return 1;
}
else if(overlap(ship,rock3)) {
ship.explode();
mySpeaker.PlayNote(500.0,0.25,0.1);
mySpeaker.PlayNote(450.0,0.25,0.1);
mySpeaker.PlayNote(400.0,0.25,0.1);
mySpeaker.PlayNote(300.0,0.25,0.1);
uLCD.printf("GAME OVER");
wait(3);
return 1;
}
else if(overlap(ship,rock4)) {
ship.explode();
mySpeaker.PlayNote(500.0,0.25,0.1);
mySpeaker.PlayNote(450.0,0.25,0.1);
mySpeaker.PlayNote(400.0,0.25,0.1);
mySpeaker.PlayNote(300.0,0.25,0.1);
uLCD.printf("GAME OVER");
wait(3);
return 1;
}
//check to see if the game is over
} //end infinite while loop
} //end main