World In Balance game

Dependencies:   4DGL-uLCD-SE PinDetect mbed

main.cpp

Committer:
jchin32
Date:
2017-11-08
Revision:
0:1305fa20a8db

File content as of revision 0:1305fa20a8db:

#include "mbed.h"
#include "MMA8452.h"
#include "ScreenObject.h"
#include "SpaceShipEarth.h"
#include "Asteroid1.h"
#include "Asteroid2.h"
#include "Asteroid3.h"
#include "Asteroid4.h"
#include "PinDetect.h"
#include "Speaker.h"
#include <ctime>

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

};

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

};

int explosion[EARTH_HEIGHT * EARTH_WIDTH] = {
    _,_,r,_,_,r,_,_,_,_,
    _,r,r,_,r,O,r,_,_,_,
    r,O,O,r,O,R,O,r,_,r,
    _,r,O,R,R,R,R,O,r,r,
    _,_,r,O,R,R,R,R,O,r,
    _,r,O,R,R,R,R,O,r,_,
    _,r,O,R,R,R,R,O,r,_,
    r,O,O,r,O,r,r,O,O,r,
    r,O,r,_,r,_,_,r,O,r,
    _,r,_,_,_,_,_,_,r,r,
};

int erase[EARTH_WIDTH * EARTH_HEIGHT] = {
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_,
    _,_,_,_,_,_,_,_,_,_, 
};

bool bombUsed = false;
bool explodeAllAsteroids = false;

Asteroid1::Asteroid1() {
    setX((rand() % (64 - EARTH_WIDTH - ASTEROID_WIDTH) + (ASTEROID_WIDTH / 2)));
    setY((rand() % (64 - EARTH_HEIGHT - ASTEROID_HEIGHT)
        + (ASTEROID_HEIGHT / 2)));
    setX((rand() % 2 == 0) ? getX() : 128 - getX());
    setY((rand() % 2 == 0) ? getY() : 128 - getY());
    setXPath((rand() % 2 + 1) * (getX() > 63 ? -1 : 1));
    setYPath((rand() % 2 + 1) * (getY() > 63 ? -1 : 1));
    setSpeed(1);
    setSprite(asteroid_sprite_1);
    setDestroyed(false);
    setHeight(ASTEROID_HEIGHT);
    setWidth(ASTEROID_WIDTH);
}

Asteroid2::Asteroid2() {
    setX((rand() % (64 - EARTH_WIDTH - ASTEROID_WIDTH) + (ASTEROID_WIDTH / 2)));
    setY((rand() % (64 - EARTH_HEIGHT - ASTEROID_HEIGHT)
        + (ASTEROID_HEIGHT / 2)));
    setX((rand() % 2 == 0) ? getX() : 128 - getX());
    setY((rand() % 2 == 0) ? getY() : 128 - getY());
    setXPath((rand() % 4 + 1) * (getX() > 63 ? -1 : 1));
    setYPath((rand() % 4 + 1) * (getY() > 63 ? -1 : 1));
    setSpeed(1);
    setSprite(asteroid_sprite_2);
    setDestroyed(false);
    setHeight(ASTEROID_HEIGHT);
    setWidth(ASTEROID_WIDTH);
}

Asteroid3::Asteroid3() {
    setX((rand() % (64 - EARTH_WIDTH - ASTEROID_WIDTH) + (ASTEROID_WIDTH / 2)));
    setY((rand() % (64 - EARTH_HEIGHT - ASTEROID_HEIGHT)
        + (ASTEROID_HEIGHT / 2)));
    setX((rand() % 2 == 0) ? getX() : 128 - getX());
    setY((rand() % 2 == 0) ? getY() : 128 - getY());
    setXPath((rand() % 2 + 1) * (getX() > 63 ? -1 : 1));
    setYPath((rand() % 2 + 1) * (getY() > 63 ? -1 : 1));
    setSpeed(1);
    setSprite(asteroid_sprite_3);
    setDestroyed(false);
    setHeight(ASTEROID_HEIGHT);
    setWidth(ASTEROID_WIDTH);
}

Asteroid4::Asteroid4() {
    setX((rand() % (64 - EARTH_WIDTH - ASTEROID_WIDTH) + (ASTEROID_WIDTH / 2)));
    setY((rand() % (64 - EARTH_HEIGHT - ASTEROID_HEIGHT)
        + (ASTEROID_HEIGHT / 2)));
    setX((rand() % 2 == 0) ? getX() : 128 - getX());
    setY((rand() % 2 == 0) ? getY() : 128 - getY());
    setXPath((rand() % 2 + 1) * (getX() > 63 ? -1 : 1));
    setYPath((rand() % 2 + 1) * (getY() > 63 ? -1 : 1));
    setSpeed(1);
    setSprite(asteroid_sprite_4);
    setDestroyed(false);
    setHeight(ASTEROID_HEIGHT);
    setWidth(ASTEROID_WIDTH);
}


bool overlap(ScreenObject & object1, ScreenObject & object2) {
    int delX = object1.getX() - object2.getX();
    int delY = object1.getY() - object2.getY();
    delX = (delX > 0 ? delX : -delX);
    delY = (delY > 0 ? delY : -delY);
    if (delX < (object1.getWidth() + object2.getWidth()) / 2) {
        if (delY < (object1.getHeight() + object2.getHeight()) / 2) {
            return true;
        }
    }
    return false;
}


void pb1_hit_callback(void) {
    if (!bombUsed) {
        explodeAllAsteroids = true;
        bombUsed = true;
        return;
    }
    return;
}

Serial pc(USBTX,USBRX);
PinDetect pb1(p16);
Speaker mySpeaker(p21);

int main() {
    set_time(0);
    pb1.mode(PullUp);
    wait(0.1);
    pb1.attach_deasserted(&pb1_hit_callback);
    pb1.setSampleFrequency();    
    uLCD_4DGL uLCD(p28, p27, p29);
    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];
    for (int i = 0; i < NUM_ASTEROIDS; i++) {
        int asteroidNum = rand() % 4 + 1;
        switch (asteroidNum) {
            case 1:
                ActiveAsteroids[i] = new Asteroid1;
                break;
            case 2:
                ActiveAsteroids[i] = new Asteroid2;
                break;
            case 3:
                ActiveAsteroids[i] = new Asteroid3;
                break;
            case 4:
                ActiveAsteroids[i] = new Asteroid4;
                break;
        }
    }
    
    SpaceShipEarth ship;
    double x = 0.0, y = 0.0, z = 0.0, factor = 50.0;
    int offsetx = 63;
    int offsety = 63;
    MMA8452 acc(p9, p10, 40000);
    acc.setBitDepth(MMA8452::BIT_DEPTH_12);
    acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_4G);
    acc.setDataRate(MMA8452::RATE_100);
    
    bool gameOver = false;
    bool gameWon = false;
    time_t startTime;
    startTime = time(0);
    time_t timeElapsed = time(0)-startTime;
    
    uLCD.filled_rectangle(0, 0, 127, 2, B); 
    mySpeaker.PlayNote(400.0, .25, .1);
    wait(0.2);
    mySpeaker.PlayNote(200.0, .25, .1);
    wait(0.2);
    mySpeaker.PlayNote(100.0, .25, .1);
    while (!gameOver) {
        if (timeElapsed >= 30) {
            gameWon = true;
            gameOver = true;
        } 
        uLCD.filled_rectangle(127 - (127*timeElapsed)/30, 0, 127, 2, _);
        if (explodeAllAsteroids) {
            for (int i = 0; i < NUM_ASTEROIDS; i++) {
                ActiveAsteroids[i]->update();
                uLCD.BLIT(ActiveAsteroids[i]->getX() - (EARTH_WIDTH / 2),
                        ActiveAsteroids[i]->getY() - (EARTH_HEIGHT / 2),
                        EARTH_WIDTH, EARTH_HEIGHT, explosion);
                mySpeaker.PlayNote(100.0, .1, .2);
                wait(0.1);
                mySpeaker.PlayNote(50.0, .1, .2);
                uLCD.BLIT(ActiveAsteroids[i]->getX() - (EARTH_WIDTH / 2),
                        ActiveAsteroids[i]->getY() - (EARTH_HEIGHT / 2),
                        EARTH_WIDTH, EARTH_HEIGHT, erase);
                delete ActiveAsteroids[i];
                int asteroidNum = rand() % 4 + 1;
                switch (asteroidNum) {
                    case 1:
                        ActiveAsteroids[i] = new Asteroid1;
                        break;
                    case 2:
                        ActiveAsteroids[i] = new Asteroid2;
                        break;
                    case 3:
                        ActiveAsteroids[i] = new Asteroid3;
                        break;
                    case 4:
                        ActiveAsteroids[i] = new Asteroid4;
                        break;
                }
            }
            explodeAllAsteroids = false;    
        }
        timeElapsed = time(0) - startTime;
        ship.update();
        for (int i = 0; i < NUM_ASTEROIDS; i++) {
            ActiveAsteroids[i]->update();
        }
        if (!acc.isXYZReady()) {
            wait(.01);
        } else {
            acc.readXYZGravity(&y, &x, &z);
            ship.setX(-1 * x * factor + offsetx);
            ship.setY(-1 * y * factor + offsety);
            ship.draw();
            for (int i = 0; i < NUM_ASTEROIDS; i++) {
                if (ActiveAsteroids[i]->getDestroyed()) {
                    delete ActiveAsteroids[i];
                    int asteroidNum = rand() % 4 + 1;
                    switch (asteroidNum) {
                        case 1:
                            ActiveAsteroids[i] = new Asteroid1;
                            break;
                        case 2:
                            ActiveAsteroids[i] = new Asteroid2;
                            break;
                        case 3:
                            ActiveAsteroids[i] = new Asteroid3;
                            break;
                        case 4:
                            ActiveAsteroids[i] = new Asteroid4;
                            break;
                    }
                }
                ActiveAsteroids[i]->draw();
                if (overlap(ship, *ActiveAsteroids[i])) {
                    gameOver = true;
                    mySpeaker.PlayNote(100.0, .1, .1);                                        
                    uLCD.BLIT(ship.getX() - (EARTH_WIDTH / 2),
                        ship.getY() - (EARTH_HEIGHT / 2),
                        EARTH_WIDTH, EARTH_HEIGHT, explosion);
                    mySpeaker.PlayNote(50.0, .1, .1);
                }
            }
        }
    }
    ship.update();
    for (int i = 0; i < NUM_ASTEROIDS; i++) {
        ActiveAsteroids[i]->update();
    }
    if (gameWon) {
        uLCD.printf("You Won!");
        mySpeaker.PlayNote(200.0, .2, .1);
        wait(.1);
        mySpeaker.PlayNote(800.0, .2, .1);
    } else {
        uLCD.printf("You lose...");
    }
}