SharpShooter

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player

MainGame.cpp

Committer:
jboettcher
Date:
2016-10-31
Revision:
15:e09ab0d14d4b
Parent:
13:67e79a582164

File content as of revision 15:e09ab0d14d4b:

#include "mbed.h"
#include "Speaker.h"
#include "uLCD_4DGL.h"
#include "SDFileSystem.h"
#include "wave_player.h"
#include "Nav_Switch.h"
#include "rtos.h"
#include "Obstacle.h"
#include "Shooter.h"
#include "Bullet.h"

/*DIRECTIVES*/
#define NUMTRIES 10

/*INSTANTIATION*/
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);

InterruptIn center(p25);
InterruptIn left(p26);
InterruptIn right(p28);

uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin;
Nav_Switch myNav( p24, p25, p26, p27, p28); //up, down, left, right, fire
SDFileSystem sd(p5, p6, p7, p8, "sd");
AnalogOut DACout(p18);
wave_player waver(&DACout);
Shooter player1;
Bullet bullet;
bool isBullet;
Mutex mutex;

/*STRUCT INITIALIZATION*/
struct TargetLocation {
    int x,y,r;
};

/*GLOBAL VARIABLES*/
int numTries;
int levelNum;
BulletLocation bulletLocation;
Obstacle obsArr[3];
TargetLocation * targetsPtr = new TargetLocation[3];
bool play = 0;
int targetY = 15;
int targetRad = 5;
int targetsLeft = 3;
bool targetsHit[3];

void startGame() {
    uLCD.background_color(BACKGROUND);
    uLCD.filled_rectangle(0,0,127,127,BLUE);
    uLCD.locate(3,6);
    uLCD.printf("Sharp Shooter!");
    wait(0.1);
    
    FILE *wave_file;
    wave_file=fopen("/sd/wavfiles/intro.wav","r");
    waver.play(wave_file);
    fclose(wave_file);
    
    wait(0.3);
    uLCD.cls();
}

void createTargets() {
    //draw all targets
    uLCD.filled_circle(24,targetY,targetRad,TARGET);
    uLCD.filled_circle(64,targetY,targetRad,TARGET);
    uLCD.filled_circle(104,targetY,targetRad,TARGET);
    targetsLeft = 3;
    for (int i=0; i<targetsLeft; i++) {
        targetsHit[i] = 0;
    }
}

void createShooter() {
    player1.drawShooter();
}

void createObstacles(int num) {
    //instantiate obstacles and store in obsArr
    if (num == 1) { //if Level 1
        obsArr[0] = Obstacle(2, 62, 50, 65);
        obsArr[0].setDirection(1);
    } else if (num == 2) { //if Level 2
        obsArr[0] = Obstacle(2, 62, 50, 65);
        obsArr[0].setDirection(1);
        obsArr[1] = Obstacle(67, 32, 115, 35);
        obsArr[1].setDirection(0);
    } else if (num == 3) { //if Level 3
        obsArr[0] = Obstacle(2, 62, 50, 65);
        obsArr[0].setDirection(1);
        obsArr[1] = Obstacle(67, 32, 115, 35);
        obsArr[1].setDirection(0);
        obsArr[2] = Obstacle(48, 48, 96, 51);
        obsArr[2].setDirection(1);        
    }
    //draw obstacles
    for (int i = 0; i < num; i++) {
        obsArr[i].drawObstacle();
    }   
}

void drawHeader() {
    mutex.lock();
    if (numTries>=9) uLCD.filled_rectangle(0,0,128,7,BLACK); //clear header if over double digits
    uLCD.locate(0,0);
    uLCD.printf("LEVEL:%d BULLETS:%d", levelNum, numTries);
    mutex.unlock();
}

void initializeLevel() {
    mutex.lock();
    uLCD.cls();
    mutex.unlock();
    numTries = NUMTRIES;
    drawHeader();
    createTargets();
    createObstacles(levelNum);
    createShooter();
}

void gameOver() {
    play = 0;
    mutex.lock();
    uLCD.filled_rectangle(0,0,127,127,RED);
    uLCD.locate(5,6);
    uLCD.printf("GAM3 0V3R");
    mutex.unlock();
    
    FILE *wave_file;
    wave_file=fopen("/sd/wavfiles/gameover.wav","r");
    waver.play(wave_file);
    fclose(wave_file);
    
    while(1); //gameOver screen forever
}

void removeBullet() {
    bullet.eraseBullet();
    isBullet = 0;
    numTries -= 1;
    drawHeader();
    if (numTries==0 && targetsLeft>0) gameOver();
}

void killTarget(BulletLocation currBullet,int i) {
    targetsHit[i] = 1;
    targetsLeft -= 1;
    uLCD.filled_circle(currBullet.x,targetY,targetRad,BLUE);
    uLCD.line(currBullet.x-targetRad,targetY+targetRad,currBullet.x+targetRad,targetY-targetRad,BLACK);
    uLCD.line(currBullet.x-targetRad,targetY-targetRad,currBullet.x+targetRad,targetY+targetRad,BLACK);
    
    FILE *wave_file;
    wave_file=fopen("/sd/wavfiles/hittarget.wav","r");
    waver.play(wave_file);
    fclose(wave_file);
}

void movingBullet(void const *args) {
    while (true) {
        if(isBullet) {
            mutex.lock();
            bullet.move();
            // Remove bullet if it hits an obstacle
            ObstLocation currObs;
            BulletLocation currBullet;
            for (int i=0; i<levelNum; i++) {
                currObs = obsArr[i].getLocation(); // {x1, y1, x2, y2}
                currBullet = bullet.getLocation(); // {x, topY, bottomY}
                if ((currBullet.topY<=currObs.y2 && currBullet.topY>=currObs.y1) || (currBullet.bottomY<=currObs.y2 && currBullet.bottomY>=currObs.y1)) {
                    if (currBullet.x>=currObs.x1 && currBullet.x<=currObs.x2) {
                        removeBullet();
                        FILE *wave_file;
                        wave_file=fopen("/sd/wavfiles/hitobstacle.wav","r");
                        waver.play(wave_file);
                        fclose(wave_file);
                    }
                }
            }
            // Remove bullet, and draw dead target if it hits a target
            if (currBullet.topY<=targetY+targetRad) {
                //if target is already hit
                if (currBullet.x==24 && targetsHit[0]==0) killTarget(currBullet,0);
                if (currBullet.x==64 && targetsHit[1]==0) killTarget(currBullet,1);
                if (currBullet.x==104 && targetsHit[2]==0) killTarget(currBullet,2);
                removeBullet();
            }
            mutex.unlock();

            Thread::wait(100);
        }   
    }
}

void movingObs(void const *args) {
    while (true) {
        if(play) {
            mutex.lock();
            if (levelNum == 1) {
                obsArr[0].move(3);
            } else if (levelNum == 2) {
                obsArr[0].move(6);
                obsArr[1].move(6);
            } else if (levelNum == 3) {
                obsArr[0].move(9);
                obsArr[1].move(9);
                obsArr[2].move(9);
            }   
            mutex.unlock();
            Thread::wait(500);
        }
    }
}

void shoot() {
    if (!isBullet) {
        bullet.drawBullet(player1.getLocation(), 115);
        isBullet = 1;
        
        FILE *wave_file;
        wave_file=fopen("/sd/wavfiles/shoot.wav","r");
        waver.play(wave_file);
        fclose(wave_file);
    }
}

int main() {
    levelNum = 1;
    isBullet = 0;
    Thread bulletThread(movingBullet);
    Thread obstacleThread(movingObs);
    startGame();
    while(1) {
        initializeLevel();
        play = 1;
        while (play) { //actual game play code
            if(targetsLeft==0) {
                play = 0;
                levelNum++;
            }
            if(!right.read()) player1.moveRight();
            if(!left.read()) player1.moveLeft();
            if(!center.read()) shoot();
            wait(0.12);
        }
    }
}