Asteroid

Dependencies:   4DGL-uLCD-SE PinDetect mbed

main.cpp

Committer:
Philipjp
Date:
2017-11-14
Revision:
0:73375f76583c

File content as of revision 0:73375f76583c:

#include "mbed.h"
#include "MMA8452.h"
#include "uLCD_4DGL.h"
#include "PinDetect.h"
#include "Speaker.h"


#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

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,_,_,_
};

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,_,_,_,_,_,_,_,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,_,_,_,_,_,_,_,X,_,_,_
};

int spaceship_explode[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,r,r,r,r,r,r,_,
    _,_,r,r,r,r,r,r,_,_,
};

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_update[EARTH_WIDTH *EARTH_HEIGHT] = {
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
};

int asteroid_update[ASTEROID_HEIGHT * ASTEROID_WIDTH] = {
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,_,_,_,_,_
};

uLCD_4DGL uLCD(p28, p27, p29); 
Serial pc(USBTX,USBRX);

class ScreenObject
{
protected:
    int x_pos, y_pos;
public:
    ScreenObject():x_pos(0),y_pos(0) {}
    ScreenObject(int x, int y):x_pos(x),y_pos(y) {}
    virtual void draw()=0;
    virtual void update()=0;
    double getX() {
        return x_pos;
    }
    double getY() {
        return y_pos;
    }
    void setX(int x){
        x_pos=x;
        }
    void setY(int y){
        y_pos=y;
        }
};
class SpaceShipEarth: public ScreenObject
{
public:
    SpaceShipEarth() {
        x_pos=63;
        y_pos=63;

    }
    void setX(double x) {
        x_pos=x;
    }
    void setY(double y) {
        y_pos=y;
    }

    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_update);
    }

};
class AbstractAsteroid: public ScreenObject
{
protected:
    int deltaX, deltaY;
};
class ConcreteAsteroid1: public AbstractAsteroid
{
public:
    ConcreteAsteroid1() {
        x_pos=rand() % 126 + 1;
        y_pos=rand() % 126 + 1;
        deltaX=rand() % 4 + 1;
        deltaY=rand() % 4 + 1;
        int ranNum=rand() % 4 + 1;
        if (ranNum==1) {
            x_pos=0*x_pos;
            deltaY=deltaY*-1;
        } else if(ranNum==2) {
            y_pos=0*y_pos;
            deltaX=deltaX*-1;
        } else if (ranNum==3) {
            x_pos=x_pos*0;
            y_pos=y_pos*0;
        } else {
            x_pos=x_pos;
            y_pos=y_pos;
            deltaX=deltaX*-1;
            deltaY=deltaY*-1;
        }
    }

    void draw() {
        uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_sprite_1);
    }
    void update() {
        uLCD.filled_rectangle(x_pos+ASTEROID_WIDTH,y_pos+ASTEROID_HEIGHT,x_pos,y_pos,BLACK);
        x_pos=x_pos+deltaX;
        y_pos=y_pos+deltaY;
        if(x_pos>125 || y_pos>125 || x_pos<1 || y_pos<1) {
            x_pos=rand() % 126 + 1;
            y_pos=rand() % 126 + 1;
            deltaX=rand() % 4 + 1;
            deltaY=rand() % 4 + 1;
            int ranNum=rand() % 4 + 1;
            if (ranNum==1) {
                x_pos=0*x_pos;
                deltaY=deltaY*-1;
            } else if(ranNum==2) {
                y_pos=0*y_pos;
                deltaX=deltaX*-1;
            } else if (ranNum==3) {
                x_pos=x_pos*0;
                y_pos=y_pos*0;
            } else {
                x_pos=x_pos;
                y_pos=y_pos;
                deltaX=deltaX*-1;
                deltaY=deltaY*-1;
            }
        }
    }
};
class ConcreteAsteroid2: public AbstractAsteroid
{
public:
    ConcreteAsteroid2() {
        x_pos=rand() % 126 + 1;
        y_pos=rand() % 126 + 1;
        deltaX=rand() % 4 + 1;
        deltaY=rand() % 4 + 1;
        int ranNum=rand() % 4 + 1;
        if (ranNum==1) {
            x_pos=0*x_pos;
            deltaY=deltaY*-1;
        } else if(ranNum==2) {
            y_pos=0*y_pos;
            deltaX=deltaX*-1;
        } else if (ranNum==3) {
            x_pos=x_pos*0;
            y_pos=y_pos*0;
        } else {
            x_pos=x_pos;
            y_pos=y_pos;
            deltaX=deltaX*-1;
            deltaY=deltaY*-1;
        }
    }

    void draw() {
        uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_sprite_2);
    }
    void update() {
        uLCD.filled_rectangle(x_pos+ASTEROID_WIDTH,y_pos+ASTEROID_HEIGHT,x_pos,y_pos,BLACK);
        x_pos=x_pos+deltaX;
        y_pos=y_pos+deltaY;
        if(x_pos>125 || y_pos>125 || x_pos<0 || y_pos<0) {
            x_pos=rand() % 126 + 1;
            y_pos=rand() % 126 + 1;
            deltaX=rand() % 4 + 1;
            deltaY=rand() % 4 + 1;
            int ranNum=rand() % 4 + 1;
            if (ranNum==1) {
                x_pos=0*x_pos;
                deltaY=deltaY*-1;
            } else if(ranNum==2) {
                y_pos=0*y_pos;
                deltaX=deltaX*-1;
            } else if (ranNum==3) {
                x_pos=x_pos*0;
                y_pos=y_pos*0;
            } else {
                x_pos=x_pos;
                y_pos=y_pos;
                deltaX=deltaX*-1;
                deltaY=deltaY*-1;
            }
        }
        
    }
};

class ConcreteAsteroid3: public AbstractAsteroid
{
public:
    ConcreteAsteroid3() {
        x_pos=rand() % 126 + 1;
        y_pos=rand() % 126 + 1;
        deltaX=rand() % 4 + 1;
        deltaY=rand() % 4 + 1;
        int ranNum=rand() % 4 + 1;
        if (ranNum==1) {
            x_pos=0*x_pos;
            deltaY=deltaY*-1;
        } else if(ranNum==2) {
            y_pos=0*y_pos;
            deltaX=deltaX*-1;
        } else if (ranNum==3) {
            x_pos=x_pos*0;
            y_pos=y_pos*0;
        } else {
            x_pos=x_pos;
            y_pos=y_pos;
            deltaX=deltaX*-1;
            deltaY=deltaY*-1;
        }
    }

    void draw() {
        uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_sprite_3);
    }
    void update() {
        uLCD.filled_rectangle(x_pos+ASTEROID_WIDTH,y_pos+ASTEROID_HEIGHT,x_pos,y_pos,BLACK);
        x_pos=x_pos+deltaX;
        y_pos=y_pos+deltaY;
        if(x_pos>125 || y_pos>125 || x_pos<1 || y_pos<1) {
            x_pos=rand() % 126 + 1;
            y_pos=rand() % 126 + 1;
            deltaX=rand() % 4 + 1;
            deltaY=rand() % 4 + 1;
            int ranNum=rand() % 4 + 1;
            if (ranNum==1) {
                x_pos=0*x_pos;
                deltaY=deltaY*-1;
            } else if(ranNum==2) {
                y_pos=0*y_pos;
                deltaX=deltaX*-1;
            } else if (ranNum==3) {
                x_pos=x_pos*0;
                y_pos=y_pos*0;
            } else {
                x_pos=x_pos;
                y_pos=y_pos;
                deltaX=deltaX*-1;
                deltaY=deltaY*-1;
            }
        }
        
    }
};

class ConcreteAsteroid4: public AbstractAsteroid
{
public:
    ConcreteAsteroid4() {
        x_pos=rand() % 126 + 1;
        y_pos=rand() % 126 + 1;
        deltaX=rand() % 4 + 1;
        deltaY=rand() % 4 + 1;
        int ranNum=rand() % 4 + 1;
        if (ranNum==1) {
            x_pos=0*x_pos;
            deltaY=deltaY*-1;
        } else if(ranNum==2) {
            y_pos=0*y_pos;
            deltaX=deltaX*-1;
        } else if (ranNum==3) {
            x_pos=x_pos*0;
            y_pos=y_pos*0;
        } else {
            x_pos=x_pos;
            y_pos=y_pos;
            deltaX=deltaX*-1;
            deltaY=deltaY*-1;
        }
    }

    void draw() {
        uLCD.BLIT(x_pos, y_pos, ASTEROID_WIDTH, ASTEROID_HEIGHT,asteroid_sprite_4);
    }
    void update() {
        uLCD.filled_rectangle(x_pos+ASTEROID_WIDTH,y_pos+ASTEROID_HEIGHT,x_pos,y_pos,BLACK);
        x_pos=x_pos+deltaX;
        y_pos=y_pos+deltaY;
        if(x_pos>125 || y_pos>125 || x_pos<1 || y_pos<1) {
            x_pos=rand() % 126 + 1;
            y_pos=rand() % 126 + 1;
            deltaX=rand() % 4 + 1;
            deltaY=rand() % 4 + 1;
            int ranNum=rand() % 4 + 1;
            if (ranNum==1) {
                x_pos=0*x_pos;
                deltaY=deltaY*-1;
            } else if(ranNum==2) {
                y_pos=0*y_pos;
                deltaX=deltaX*-1;
            } else if (ranNum==3) {
                x_pos=x_pos*0;
                y_pos=y_pos*0;
            } else {
                x_pos=x_pos;
                y_pos=y_pos;
                deltaX=deltaX*-1;
                deltaY=deltaY*-1;
            }
        }
        
    }
};

bool overlap(ScreenObject & objectA, ScreenObject & objectB)
{
    int EarthX=objectA.getX();
    int EarthY=objectA.getY();
    
    int TXSB=EarthX-15;
    int TYSB=EarthY-12;
    int LXSB=EarthX+10;
    int LYSB=EarthY+10;
    int AstX=objectB.getX();
    int AstY=objectB.getY();
    
    if ((AstX>TXSB && AstX<LXSB) && (AstY>TYSB && AstY<LYSB)){
        return true;
        }
    else{
        return false;
        }
}


Speaker mySpeaker(p21);
bool BombUsed=false;
bool ExplodeAllAsteroids=false;
//DigitalIn pb1(p16);

PinDetect pb1(p16);
void pb1_hit_callback (void)
        {
            if (!BombUsed )
            {
                
            ExplodeAllAsteroids = true;
            BombUsed = true;
            
            }
        }


int main()
{
    uLCD.baudrate(300000);
    wait(0.2);
    srand(time(0)); 

    ScreenObject * ActiveAsteroids[NUM_ASTEROIDS];

    SpaceShipEarth ship;
    ConcreteAsteroid1 Ast1;
    ConcreteAsteroid2 Ast2;
    ConcreteAsteroid3 Ast3;
    ConcreteAsteroid4 Ast4;
    
    //ship draw
    ActiveAsteroids[0]=&Ast1;
    ActiveAsteroids[1]=&Ast2;
    ActiveAsteroids[2]=&Ast3;
    ActiveAsteroids[3]=&Ast4;



    double x=0,y=0,z=0;
    double factor=50;


    MMA8452 acc(p9, p10, 40000);   
    acc.setBitDepth(MMA8452::BIT_DEPTH_12);
    acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_4G);
    acc.setDataRate(MMA8452::RATE_100);
    set_time(0);
    time_t startTime;
    startTime = time(0);
    time_t timeElapsed;
    timeElapsed= time(0)-startTime; // timeBar;



    int x_pos=63;
    int y_pos=63;
    bool check=true;
    
    
     pb1.mode(PullUp);
     pb1.attach_asserted(&pb1_hit_callback);
     pb1.setSampleFrequency();
   
    
    for (int i=0; i<NUM_ASTEROIDS; i++) {
        ActiveAsteroids[i]->draw();
        }
    
    while (timeElapsed<3 && check) {
        timeElapsed= time(0)-startTime;
        uLCD.filled_rectangle(0,0,126,3,BLACK);
        uLCD.filled_rectangle(0,0,126-(126/29) * timeElapsed,3,BLUE);
      
        
        for (int i=0; i<NUM_ASTEROIDS; i++) {
            ActiveAsteroids[i]->update();    
        }
        ship.update();



        if(!acc.isXYZReady()) {
            wait(0.01);
        } else {
            acc.readXYZGravity(&x,&y,&z); //notice this is passed by reference use pointers
            ship.setX(-x*factor+x_pos);
            ship.setY(-y*factor+y_pos);
            ship.draw();
        }

        for (int i=0; i<NUM_ASTEROIDS; i++) {
            ActiveAsteroids[i]->draw();
            if (overlap(ship,*ActiveAsteroids[i])){
                uLCD.BLIT(ship.getX(),ship.getY(),EARTH_WIDTH,EARTH_HEIGHT,spaceship_explode);
                mySpeaker.PlayNote(160.0 + x*200, .4 + 0.2*y, 0.05);
                check=false;
                }
        }
        
        if (ExplodeAllAsteroids){    
            for (int i=0; i<NUM_ASTEROIDS; i++) {
                ActiveAsteroids[i]->update();
                ActiveAsteroids[i]->setX(127);  
                ActiveAsteroids[i]->setY(127);
            } 
            mySpeaker.PlayNote(880, .750, 0.015);
            ExplodeAllAsteroids=false;
        }
        
        

    }
    if (!check){
        uLCD.cls();
        mySpeaker.PlayNote(658, .125, 0.015);
        mySpeaker.PlayNote(1320, .500, 0.015);
        mySpeaker.PlayNote(990, .250, 0.015);
        mySpeaker.PlayNote(1056, .250, 0.015);
        mySpeaker.PlayNote(1188, .250, 0.015);
        mySpeaker.PlayNote(1320, .125, 0.015);
        mySpeaker.PlayNote(1188, .125, 0.015);
        mySpeaker.PlayNote(1056, .250, 0.015);
        mySpeaker.PlayNote(990, .250, 0.015);
        mySpeaker.PlayNote(880, .500, 0.015);
        mySpeaker.PlayNote(880, .250, 0.015);
        mySpeaker.PlayNote(1056, .250, 0.015);
        mySpeaker.PlayNote(1320, .500, 0.015);
        mySpeaker.PlayNote(1188, .250, 0.015);
        mySpeaker.PlayNote(1056, .250, 0.015);
        mySpeaker.PlayNote(990, .750, 0.015);
        mySpeaker.PlayNote(1056, .250, 0.015);
        mySpeaker.PlayNote(1188, .5, 0.015);
        mySpeaker.PlayNote(1320, .500, 0.015);
        mySpeaker.PlayNote(1056, .500, 0.015);
        mySpeaker.PlayNote(880, .500, 0.015);
        mySpeaker.PlayNote(880, .750, 0.015);
        
        uLCD.locate(5,8);
        uLCD.printf("Game Over!");
        }
    else{
        uLCD.cls();
        uLCD.locate(5,5);
        uLCD.printf("Congrat!\n");
        uLCD.printf("YOU SAVE THE WORLD");
        }
}