Asteroid

Dependencies:   4DGL-uLCD-SE PinDetect mbed

Revision:
0:73375f76583c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Nov 14 18:03:31 2017 +0000
@@ -0,0 +1,606 @@
+#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");
+        }
+}
\ No newline at end of file