A simple asteroids-like game utilizing various Mbed-compatible sensors

Dependencies:   mbed 4DGL-uLCD-SE PinDetect

main.cpp

Committer:
sralph3
Date:
2019-01-03
Revision:
8:137330cfe63d
Parent:
7:b5372b042ac7

File content as of revision 8:137330cfe63d:

// ## MBED INCLUDES ##
#include "uLCD_4DGL.h"
#include "MMA8452.h"
#include "Speaker.h"
#include "PinDetect.h"

// ## CUSTOM INCLUDES ##
#include "SSE.h"
#include "ConcreteAsteroid1.h"
#include "ConcreteAsteroid2.h"
#include "ConcreteAsteroid3.h"
#include "ConcreteAsteroid4.h"
#include "overlap.h"

// ## MATH ##
#include <math.h>

// ## CUSTOM DEFINES ##
#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

// ## VARIOUS MBED INSTANTIATIONS ##
uLCD_4DGL uLCD(p28, p27, p29);
Serial pc(USBTX,USBRX);
MMA8452 acc(p9, p10, 40000);
Speaker mySpeaker(p21);
PinDetect pb1(p18);

// ## GLOBAL VARS FOR BOMB BUTTON ##
bool BombUsed = false;
bool ExplodeAllAsteroids = false;

// ## SET UP PUSHBUTTON FOR INTURRUPT ##
void pb1_hit_callback (void)
{
    if (!BombUsed ){
        ExplodeAllAsteroids = true;
        BombUsed = true;
        mySpeaker.PlayNote(100.0,0.25,0.1);
    }
}
// ##  SPRITES ## 
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,_,_,_
};

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

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 exp1[EARTH_WIDTH *EARTH_HEIGHT] = {
    _,_,S,S,S,S,S,S,_,_,
    _,R,r,r,r,r,r,r,S,R,
    S,r,R,O,O,O,O,r,R,S,
    S,r,O,R,R,R,R,R,r,S,
    S,r,O,R,R,R,R,r,r,S,
    S,r,O,R,R,R,R,r,r,S,
    S,r,O,R,R,R,r,r,r,S,
    S,r,R,R,O,O,O,O,O,S,
    S,r,r,r,O,r,r,r,S,_,
    _,S,S,S,S,S,S,S,_,_,
};

// ## MAIN ##
int main() { 
    // ## SETUP LCD BAUDRATE, PB PULLUP, AND SRAND ##
    uLCD.baudrate(300000);
    wait(0.2);
    pb1.mode(PullUp);
    wait(0.1);
    srand(time(0));
    
    
    // ## SET PARAMETERS FOR ACCELEROMETER ##
    acc.setBitDepth(MMA8452::BIT_DEPTH_12);
    acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_4G);
    acc.setDataRate(MMA8452::RATE_100);
   
    // ## SETUP INTURRUPT CALLBACK FUNCTION FOR A PB HIT ##
    pb1.attach_deasserted(&pb1_hit_callback);
    // ## START SAMPLING PB CALLBACK ##
    pb1.setSampleFrequency();
    
    // ## CREATE ARRAY OF SCREENOBJECTS (AND SHIP) ##
    ScreenObject *AstAry[NUM_ASTEROIDS];
    AstAry[0] = new ConcreteAsteroid1;
    AstAry[1] = new ConcreteAsteroid2;
    AstAry[2] = new ConcreteAsteroid3;
    AstAry[3] = new ConcreteAsteroid4;
    SSE ship;
    
    // ## SETUP TIME & ELAPSED TIME ##
    time_t startTime;
    startTime = time(0);
    time_t timeElapsed = time(0)-startTime;
    
    // ## GAME LOOP ##
    while (true){
        uLCD.cls();
        
        // ## TAKE TIME ELAPSED, CONVERT TO OUT OF 30SEC, SCALE TO SCREN SIZE ##
        timeElapsed = time(0)-startTime;
        double t = (double)timeElapsed;
        double tw = (t/30)*SCREEN_MAX;
        uLCD.filled_rectangle(0, 0 , SCREEN_MAX-ceil(tw) , 5, G);
        
        // ## WINNING IF STATEMENT ##
        if (timeElapsed >= 30){
            mySpeaker.PlayNote(600.0,0.25,0.2);
            mySpeaker.PlayNote(800.0,0.25,0.1);
            mySpeaker.PlayNote(900.0,0.25,0.1);
            uLCD.printf("\nYOU WIN!\n PRESS BUTTON TO\n RESTART");
            wait(1);
            return 0;
        }
        
        // ## BOMB IF STATEMENT ##
        if (ExplodeAllAsteroids){
            for(int i=0; i < NUM_ASTEROIDS; i++){
                int rando = (rand() % 4);
                
                if (rando == 0) {
                    AstAry[i] = new ConcreteAsteroid1;   
                } else if (rando == 1) {
                    AstAry[i] = new ConcreteAsteroid2;   
                } else if (rando == 2) {
                    AstAry[i] = new ConcreteAsteroid3;   
                } else {
                    AstAry[i] = new ConcreteAsteroid4;   
                }
            }
            ExplodeAllAsteroids = false;
        }
        
        ship.update();
        
        // ## LOOP THROUGH ASTROID ARY, SEE IF OOB ##
        for(int i=0; i < NUM_ASTEROIDS; i++){
            AstAry[i]->update();
            if(AstAry[i]->outB()){
                int rando = (rand() % 4);
                
                if (rando == 0) {
                    AstAry[i] = new ConcreteAsteroid1;   
                } else if (rando == 1) {
                    AstAry[i] = new ConcreteAsteroid2;   
                } else if (rando == 2) {
                    AstAry[i] = new ConcreteAsteroid3;   
                } else {
                    AstAry[i] = new ConcreteAsteroid4;   
                }
            }
            
            // ## LOSING IF STATEMENT ##
            if(overlap( ship, *AstAry[i])){
                uLCD.BLIT(ship.xpos, ship.ypos, EARTH_WIDTH, EARTH_HEIGHT, exp1);
                mySpeaker.PlayNote(800.0,0.25,0.1);
                mySpeaker.PlayNote(400.0,0.25,0.1);
                mySpeaker.PlayNote(200.0,0.25,0.1);
                uLCD.printf("\nGAME OVER\n");
                wait(2);
                return 0;
            }
            AstAry[i]->draw();
        }
        ship.draw();
        wait(.1);
    }
}