SharpShooter
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player
SharpShooter
Overview¶
SharpShooter is a hyper-interactive third person shooting game. Your job is to complete all three levels by shooting the targets using timing and accuracy. As the levels increase, you will face more moving obstacles that will block your shot and test your shooting expertise.
Gameplay¶
Controls¶
Using Navigation Switch or Joystick:
- Left = Move Left
- Right = Move Right
- Center = Shoot
Links to Necessary Components¶
Joystick: https://developer.mbed.org/users/4180_1/notebook/using-a-navigation-switch-digital-joystick/
uLCD: https://developer.mbed.org/users/4180_1/notebook/ulcd-144-g2-128-by-128-color-lcd/
sD Card Reader: https://developer.mbed.org/cookbook/SD-Card-File-System
Amplifier (TPA2005D1 Class D) and Speaker: https://developer.mbed.org/users/4180_1/notebook/tpa2005d1-class-d-audio-amp/
Code¶
Import programECE4180_Lab4_Sharpshooter
SharpShooter
MainGame.cpp
#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(3); obsArr[1].move(6); } else if (levelNum == 3) { obsArr[0].move(3); obsArr[1].move(6); 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); } } }