Simple implementation of Guitar Hero with mbed.

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

Committer:
gboggs3
Date:
Mon Mar 14 17:59:32 2016 +0000
Revision:
0:58d424fe40b9
Original working version that received checkoff. 3/14/2016

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gboggs3 0:58d424fe40b9 1 /*===================================================================
gboggs3 0:58d424fe40b9 2 --------------------- Guitar Hero mbed Program ----------------------
gboggs3 0:58d424fe40b9 3
gboggs3 0:58d424fe40b9 4 This program recreates the classic Guitar Hero game using the mbed
gboggs3 0:58d424fe40b9 5 processor, along with various other peripherals, such as capacitive
gboggs3 0:58d424fe40b9 6 touch sensors, an IR sensor, and a uLCD display.
gboggs3 0:58d424fe40b9 7
gboggs3 0:58d424fe40b9 8 Written for:
gboggs3 0:58d424fe40b9 9 Georgia Institute of Technology
gboggs3 0:58d424fe40b9 10 ECE 4180, Lab 4, Section B
gboggs3 0:58d424fe40b9 11 Dr. James Hamblen
gboggs3 0:58d424fe40b9 12
gboggs3 0:58d424fe40b9 13 Authors:
gboggs3 0:58d424fe40b9 14 Garren Boggs
gboggs3 0:58d424fe40b9 15 Anthony Jones
gboggs3 0:58d424fe40b9 16 ===================================================================*/
gboggs3 0:58d424fe40b9 17
gboggs3 0:58d424fe40b9 18 #include "mbed.h"
gboggs3 0:58d424fe40b9 19 #include "rtos.h" //For threading
gboggs3 0:58d424fe40b9 20 #include "uLCD_4DGL.h" //Display
gboggs3 0:58d424fe40b9 21 #include "SDFileSystem.h" //SD card functionality
gboggs3 0:58d424fe40b9 22 #include "wave_player.h" //For playing music
gboggs3 0:58d424fe40b9 23 #include "MCP23S17.h" //Serial PC for debugging
gboggs3 0:58d424fe40b9 24 #include <mpr121.h> //Capacitive touch sensors
gboggs3 0:58d424fe40b9 25 #include <stdlib.h>
gboggs3 0:58d424fe40b9 26 #include <time.h>
gboggs3 0:58d424fe40b9 27
gboggs3 0:58d424fe40b9 28 #define NOTE_START 24
gboggs3 0:58d424fe40b9 29 #define NOTE_HEIGHT 9
gboggs3 0:58d424fe40b9 30 #define NOTE_WIDTH 27
gboggs3 0:58d424fe40b9 31 #define MISS 128
gboggs3 0:58d424fe40b9 32 #define SPEED 3
gboggs3 0:58d424fe40b9 33 #define HIT_TOP 98
gboggs3 0:58d424fe40b9 34 #define HIT_BOT 125
gboggs3 0:58d424fe40b9 35 #define VICTORY_THRESHOLD 50
gboggs3 0:58d424fe40b9 36
gboggs3 0:58d424fe40b9 37 bool paused = false; //If paused, stop gameplay and show on screen
gboggs3 0:58d424fe40b9 38 bool gameOver = false; //Occurs if HP reaches zero
gboggs3 0:58d424fe40b9 39 bool victory = false;
gboggs3 0:58d424fe40b9 40 bool resetDisplay = false; //After resetting game or unpausing
gboggs3 0:58d424fe40b9 41
gboggs3 0:58d424fe40b9 42 bool gHit = false;
gboggs3 0:58d424fe40b9 43 bool rHit = false;
gboggs3 0:58d424fe40b9 44 bool yHit = false;
gboggs3 0:58d424fe40b9 45 bool bHit = false;
gboggs3 0:58d424fe40b9 46
gboggs3 0:58d424fe40b9 47 int hp = 260; //Hitpoint count
gboggs3 0:58d424fe40b9 48 int score = 0; //Score count
gboggs3 0:58d424fe40b9 49 int combo = 0; //Combo count
gboggs3 0:58d424fe40b9 50 int notesCreated = 0; //Victory after threshold
gboggs3 0:58d424fe40b9 51
gboggs3 0:58d424fe40b9 52 /* Note locations. The values are the x and y positions respectively.
gboggs3 0:58d424fe40b9 53 A value of -1 for these coordinates indicates that the specific
gboggs3 0:58d424fe40b9 54 note is currently not on the screen. */
gboggs3 0:58d424fe40b9 55 int gNote[2]= {0,-1}; //Current GREEN note location.
gboggs3 0:58d424fe40b9 56 int rNote[2]= {NOTE_WIDTH+1,-1}; //Current RED note location.
gboggs3 0:58d424fe40b9 57 int yNote[2]= {2*NOTE_WIDTH+2,-1}; //Current YELLOW note location.
gboggs3 0:58d424fe40b9 58 int bNote[2]= {3*NOTE_WIDTH+3,-1}; //Current BLUE note location.
gboggs3 0:58d424fe40b9 59
gboggs3 0:58d424fe40b9 60 //-------------------------------------------------------------------
gboggs3 0:58d424fe40b9 61 /* Instantiates the capacitive touch sensors. These will be used for
gboggs3 0:58d424fe40b9 62 determining which notes have been pressed by the user. */
gboggs3 0:58d424fe40b9 63
gboggs3 0:58d424fe40b9 64 /* Setup the i2c bus on pins 9 and 10 */
gboggs3 0:58d424fe40b9 65 I2C i2c(p9, p10);
gboggs3 0:58d424fe40b9 66
gboggs3 0:58d424fe40b9 67 /* Setup the Mpr121: */
gboggs3 0:58d424fe40b9 68 Mpr121 notes(&i2c, Mpr121::ADD_VSS);
gboggs3 0:58d424fe40b9 69 //-------------------------------------------------------------------
gboggs3 0:58d424fe40b9 70
gboggs3 0:58d424fe40b9 71 //-------------------------------------------------------------------
gboggs3 0:58d424fe40b9 72 /* Create an interrupt receiver to detect when the user has
gboggs3 0:58d424fe40b9 73 strummed. */
gboggs3 0:58d424fe40b9 74 InterruptIn interruptStrum(p26);
gboggs3 0:58d424fe40b9 75 //-------------------------------------------------------------------
gboggs3 0:58d424fe40b9 76
gboggs3 0:58d424fe40b9 77 //-------------------------------------------------------------------
gboggs3 0:58d424fe40b9 78 /* Initialize SD Card Reader to import song to be played during the
gboggs3 0:58d424fe40b9 79 game. */
gboggs3 0:58d424fe40b9 80 SDFileSystem sd(p5, p6, p7, p8, "sd");
gboggs3 0:58d424fe40b9 81
gboggs3 0:58d424fe40b9 82 /* Initializes the wave player to actually play the song. */
gboggs3 0:58d424fe40b9 83 AnalogOut DACout (p18);
gboggs3 0:58d424fe40b9 84 wave_player player(&DACout);
gboggs3 0:58d424fe40b9 85 //-------------------------------------------------------------------
gboggs3 0:58d424fe40b9 86
gboggs3 0:58d424fe40b9 87 //-------------------------------------------------------------------
gboggs3 0:58d424fe40b9 88 /* Initializes the uLCD display as a UI for the game */
gboggs3 0:58d424fe40b9 89 uLCD_4DGL uLCD(p28,p27,p30);
gboggs3 0:58d424fe40b9 90
gboggs3 0:58d424fe40b9 91 /* Create an interrupt to allow the user to pause the game, this
gboggs3 0:58d424fe40b9 92 freezing the game UI. */
gboggs3 0:58d424fe40b9 93 InterruptIn interruptPause(p16);
gboggs3 0:58d424fe40b9 94 //-------------------------------------------------------------------
gboggs3 0:58d424fe40b9 95
gboggs3 0:58d424fe40b9 96 //-------------------------------------------------------------------
gboggs3 0:58d424fe40b9 97 /* Initialize the mbed LEDs for testing and debugging purposes. */
gboggs3 0:58d424fe40b9 98 DigitalOut led1(LED1);
gboggs3 0:58d424fe40b9 99 DigitalOut led2(LED2);
gboggs3 0:58d424fe40b9 100 DigitalOut led3(LED3);
gboggs3 0:58d424fe40b9 101 DigitalOut led4(LED4);
gboggs3 0:58d424fe40b9 102
gboggs3 0:58d424fe40b9 103 /* Setup the Serial to the PC for debugging */
gboggs3 0:58d424fe40b9 104 Serial pc(USBTX, USBRX);
gboggs3 0:58d424fe40b9 105 DigitalIn test(p24);
gboggs3 0:58d424fe40b9 106 //-------------------------------------------------------------------
gboggs3 0:58d424fe40b9 107
gboggs3 0:58d424fe40b9 108 /*
gboggs3 0:58d424fe40b9 109 * Detects when the user has strum in order to play a note. This occurs
gboggs3 0:58d424fe40b9 110 * when the user waves a hand close to the IR sensor. If close enough,
gboggs3 0:58d424fe40b9 111 * the defined threshold will be passes and registered as a strum.
gboggs3 0:58d424fe40b9 112 */
gboggs3 0:58d424fe40b9 113 void strumInterrupt()
gboggs3 0:58d424fe40b9 114 {
gboggs3 0:58d424fe40b9 115 //For resetting a game
gboggs3 0:58d424fe40b9 116 if(gameOver || victory)
gboggs3 0:58d424fe40b9 117 {
gboggs3 0:58d424fe40b9 118 gNote[1] = -1;
gboggs3 0:58d424fe40b9 119 rNote[1] = -1;
gboggs3 0:58d424fe40b9 120 yNote[1] = -1;
gboggs3 0:58d424fe40b9 121 bNote[1] = -1;
gboggs3 0:58d424fe40b9 122 notesCreated = 0;
gboggs3 0:58d424fe40b9 123 score = 0;
gboggs3 0:58d424fe40b9 124 combo = 0;
gboggs3 0:58d424fe40b9 125 hp = 260;
gboggs3 0:58d424fe40b9 126
gboggs3 0:58d424fe40b9 127 gHit = false;
gboggs3 0:58d424fe40b9 128 rHit = false;
gboggs3 0:58d424fe40b9 129 yHit = false;
gboggs3 0:58d424fe40b9 130 bHit = false;
gboggs3 0:58d424fe40b9 131
gboggs3 0:58d424fe40b9 132 resetDisplay = true;
gboggs3 0:58d424fe40b9 133 paused = false;
gboggs3 0:58d424fe40b9 134 gameOver = false;
gboggs3 0:58d424fe40b9 135 victory = false;
gboggs3 0:58d424fe40b9 136 return;
gboggs3 0:58d424fe40b9 137 }
gboggs3 0:58d424fe40b9 138
gboggs3 0:58d424fe40b9 139 //Read values of selected notes off of capacitive touch sensor
gboggs3 0:58d424fe40b9 140 int value = notes.read(0x00);
gboggs3 0:58d424fe40b9 141 value += notes.read(0x01)<<8;
gboggs3 0:58d424fe40b9 142
gboggs3 0:58d424fe40b9 143 //Determine if a note or combination of notes is being pressed
gboggs3 0:58d424fe40b9 144 if((value == 1 || value == 3 || value == 5 || value == 7 || value == 9 || value == 11 || value == 13 || value == 15) &&
gboggs3 0:58d424fe40b9 145 gNote[1] < HIT_BOT && gNote[1] > HIT_TOP)
gboggs3 0:58d424fe40b9 146 gHit = true;
gboggs3 0:58d424fe40b9 147 if((value == 2 || value == 3 || value == 6 || value == 7 || value == 10 || value == 11 || value == 14 || value == 15) &&
gboggs3 0:58d424fe40b9 148 rNote[1] < HIT_BOT && rNote[1] > HIT_TOP)
gboggs3 0:58d424fe40b9 149 rHit = true;
gboggs3 0:58d424fe40b9 150 if((value == 4 || value == 5 || value == 6 || value == 7 || value == 12 || value == 13 || value == 14 || value == 15) &&
gboggs3 0:58d424fe40b9 151 yNote[1] < HIT_BOT && yNote[1] > HIT_TOP)
gboggs3 0:58d424fe40b9 152 yHit = true;
gboggs3 0:58d424fe40b9 153 if((value == 8 || value == 9 || value == 10 || value == 11 || value == 12 || value == 13 || value == 14 || value == 15) &&
gboggs3 0:58d424fe40b9 154 bNote[1] < HIT_BOT && bNote[1] > HIT_TOP)
gboggs3 0:58d424fe40b9 155 bHit = true;
gboggs3 0:58d424fe40b9 156
gboggs3 0:58d424fe40b9 157 }
gboggs3 0:58d424fe40b9 158
gboggs3 0:58d424fe40b9 159 /*
gboggs3 0:58d424fe40b9 160 * Updates the game display's life bar counter. If life bar drops below zero,
gboggs3 0:58d424fe40b9 161 * game ends.
gboggs3 0:58d424fe40b9 162 */
gboggs3 0:58d424fe40b9 163 void updateLifeBar()
gboggs3 0:58d424fe40b9 164 {
gboggs3 0:58d424fe40b9 165 int i;
gboggs3 0:58d424fe40b9 166 int offset = 0;
gboggs3 0:58d424fe40b9 167
gboggs3 0:58d424fe40b9 168 //Creates life bars on the game UI for the user to know how well they are doing.
gboggs3 0:58d424fe40b9 169 //If the user loses HP, the bars will decrease, and as the user repleneshes their
gboggs3 0:58d424fe40b9 170 //HP, the bars will begin to rise.
gboggs3 0:58d424fe40b9 171 for(i = 0; i < 8; i++)
gboggs3 0:58d424fe40b9 172 {
gboggs3 0:58d424fe40b9 173 if(hp < (260 - i*10))
gboggs3 0:58d424fe40b9 174 uLCD.filled_rectangle(4*NOTE_WIDTH+6,3*i+offset,124,3*(i+1)+offset,BLACK);
gboggs3 0:58d424fe40b9 175 else
gboggs3 0:58d424fe40b9 176 uLCD.filled_rectangle(4*NOTE_WIDTH+6,3*i+offset,124,3*(i+1)+offset,GREEN);
gboggs3 0:58d424fe40b9 177 offset += 2;
gboggs3 0:58d424fe40b9 178 }
gboggs3 0:58d424fe40b9 179 for(i = 8; i < 19; i++)
gboggs3 0:58d424fe40b9 180 {
gboggs3 0:58d424fe40b9 181 if(hp < (260 - i*10))
gboggs3 0:58d424fe40b9 182 uLCD.filled_rectangle(4*NOTE_WIDTH+6,3*i+offset,124,3*(i+1)+offset,BLACK);
gboggs3 0:58d424fe40b9 183 else
gboggs3 0:58d424fe40b9 184 uLCD.filled_rectangle(4*NOTE_WIDTH+6,3*i+offset,124,3*(i+1)+offset,YELLOW);
gboggs3 0:58d424fe40b9 185 offset += 2;
gboggs3 0:58d424fe40b9 186 }
gboggs3 0:58d424fe40b9 187 for(i = 19; i < 26; i++)
gboggs3 0:58d424fe40b9 188 {
gboggs3 0:58d424fe40b9 189 if(hp < (260 - i*10))
gboggs3 0:58d424fe40b9 190 uLCD.filled_rectangle(4*NOTE_WIDTH+6,3*i+offset,124,3*(i+1)+offset,BLACK);
gboggs3 0:58d424fe40b9 191 else
gboggs3 0:58d424fe40b9 192 uLCD.filled_rectangle(4*NOTE_WIDTH+6,3*i+offset,124,3*(i+1)+offset,RED);
gboggs3 0:58d424fe40b9 193 offset += 2;
gboggs3 0:58d424fe40b9 194 }
gboggs3 0:58d424fe40b9 195 }
gboggs3 0:58d424fe40b9 196
gboggs3 0:58d424fe40b9 197 /*
gboggs3 0:58d424fe40b9 198 * Initializes the game UI with the predefined background. There are
gboggs3 0:58d424fe40b9 199 * four specific notes the user can play, and thus there will be four
gboggs3 0:58d424fe40b9 200 * distinct lanes that are drawn initially.
gboggs3 0:58d424fe40b9 201 */
gboggs3 0:58d424fe40b9 202 void setupDisplay()
gboggs3 0:58d424fe40b9 203 {
gboggs3 0:58d424fe40b9 204 //Background display
gboggs3 0:58d424fe40b9 205 uLCD.cls();
gboggs3 0:58d424fe40b9 206 uLCD.background_color(BLACK);
gboggs3 0:58d424fe40b9 207 uLCD.line(NOTE_WIDTH,NOTE_START-4,NOTE_WIDTH,127,WHITE);
gboggs3 0:58d424fe40b9 208 uLCD.line(2*NOTE_WIDTH+1,NOTE_START-4,2*NOTE_WIDTH+1,127,WHITE);
gboggs3 0:58d424fe40b9 209 uLCD.line(3*NOTE_WIDTH+2,NOTE_START-4,3*NOTE_WIDTH+2,127,WHITE);
gboggs3 0:58d424fe40b9 210 uLCD.filled_rectangle(4*NOTE_WIDTH+3,0,4*NOTE_WIDTH+4,127,WHITE);
gboggs3 0:58d424fe40b9 211 uLCD.filled_rectangle(126,0,127,127,WHITE);
gboggs3 0:58d424fe40b9 212 uLCD.line(0,NOTE_START-4,4*NOTE_WIDTH+3,NOTE_START-4,WHITE);
gboggs3 0:58d424fe40b9 213 uLCD.rectangle(0,127-(NOTE_HEIGHT+2),NOTE_WIDTH-1,127,GREEN);
gboggs3 0:58d424fe40b9 214 uLCD.rectangle(NOTE_WIDTH+1,127-(NOTE_HEIGHT+2),2*NOTE_WIDTH,127,RED);
gboggs3 0:58d424fe40b9 215 uLCD.rectangle(2*NOTE_WIDTH+2,127-(NOTE_HEIGHT+2),3*NOTE_WIDTH+1,127,YELLOW);
gboggs3 0:58d424fe40b9 216 uLCD.rectangle(3*NOTE_WIDTH+3,127-(NOTE_HEIGHT+2),4*NOTE_WIDTH+2,127,BLUE);
gboggs3 0:58d424fe40b9 217
gboggs3 0:58d424fe40b9 218 //Scoreboard
gboggs3 0:58d424fe40b9 219 uLCD.printf("SCORE: %d\nCOMBO: %d",score,combo);
gboggs3 0:58d424fe40b9 220
gboggs3 0:58d424fe40b9 221 //Initialize life bar
gboggs3 0:58d424fe40b9 222 updateLifeBar();
gboggs3 0:58d424fe40b9 223 }
gboggs3 0:58d424fe40b9 224
gboggs3 0:58d424fe40b9 225 /*
gboggs3 0:58d424fe40b9 226 * Calculates the dimensions for a specific note, based on its
gboggs3 0:58d424fe40b9 227 * current position.
gboggs3 0:58d424fe40b9 228 */
gboggs3 0:58d424fe40b9 229 void calculateNoteDims(int pos[], int dims[])
gboggs3 0:58d424fe40b9 230 {
gboggs3 0:58d424fe40b9 231 //If currently not on screen, do nothing.
gboggs3 0:58d424fe40b9 232 if(pos[1] < 0 || pos[1] > MISS)
gboggs3 0:58d424fe40b9 233 {
gboggs3 0:58d424fe40b9 234 dims[0] = 0;
gboggs3 0:58d424fe40b9 235 dims[1] = 0;
gboggs3 0:58d424fe40b9 236 dims[2] = 0;
gboggs3 0:58d424fe40b9 237 dims[3] = 0;
gboggs3 0:58d424fe40b9 238 return;
gboggs3 0:58d424fe40b9 239 }
gboggs3 0:58d424fe40b9 240
gboggs3 0:58d424fe40b9 241 //Otherwise calculate dimensions
gboggs3 0:58d424fe40b9 242 dims[0] = pos[0]; //x-left dimension
gboggs3 0:58d424fe40b9 243 dims[2] = pos[0] + NOTE_WIDTH - 1; //x-right dimension
gboggs3 0:58d424fe40b9 244
gboggs3 0:58d424fe40b9 245 dims[1] = (pos[1] - (NOTE_HEIGHT - 1)) > 0 ? pos[1] : 0; //y-bottom dimension
gboggs3 0:58d424fe40b9 246 dims[3] = (pos[1] - (NOTE_HEIGHT - 1)) > 0 ? dims[1] + (NOTE_HEIGHT - 1) : pos[1]; //y-top dimension
gboggs3 0:58d424fe40b9 247
gboggs3 0:58d424fe40b9 248 return;
gboggs3 0:58d424fe40b9 249 }
gboggs3 0:58d424fe40b9 250
gboggs3 0:58d424fe40b9 251 /*
gboggs3 0:58d424fe40b9 252 * Pauses the game.
gboggs3 0:58d424fe40b9 253 */
gboggs3 0:58d424fe40b9 254 void pauseGame()
gboggs3 0:58d424fe40b9 255 {
gboggs3 0:58d424fe40b9 256 if(paused)
gboggs3 0:58d424fe40b9 257 {
gboggs3 0:58d424fe40b9 258 resetDisplay = true;
gboggs3 0:58d424fe40b9 259 }
gboggs3 0:58d424fe40b9 260 paused = !paused;
gboggs3 0:58d424fe40b9 261 wait(0.2);
gboggs3 0:58d424fe40b9 262 }
gboggs3 0:58d424fe40b9 263
gboggs3 0:58d424fe40b9 264 /*
gboggs3 0:58d424fe40b9 265 * The game loop. This continuously updates the display with the notes, and
gboggs3 0:58d424fe40b9 266 * acts accordingly if the user has strum, and a note has been hit. If the
gboggs3 0:58d424fe40b9 267 * game is paused, the notes will cease movement, and a text displaying so
gboggs3 0:58d424fe40b9 268 * will appear on the screen.
gboggs3 0:58d424fe40b9 269 */
gboggs3 0:58d424fe40b9 270 void playGame(void const *args)
gboggs3 0:58d424fe40b9 271 {
gboggs3 0:58d424fe40b9 272 int gDims[4];
gboggs3 0:58d424fe40b9 273 int rDims[4];
gboggs3 0:58d424fe40b9 274 int yDims[4];
gboggs3 0:58d424fe40b9 275 int bDims[4];
gboggs3 0:58d424fe40b9 276
gboggs3 0:58d424fe40b9 277 while(1)
gboggs3 0:58d424fe40b9 278 {
gboggs3 0:58d424fe40b9 279 if(!gameOver && !victory && !paused)
gboggs3 0:58d424fe40b9 280 {
gboggs3 0:58d424fe40b9 281 //Resets display if game has been reset or unpaused
gboggs3 0:58d424fe40b9 282 if(resetDisplay)
gboggs3 0:58d424fe40b9 283 {
gboggs3 0:58d424fe40b9 284 resetDisplay = false;
gboggs3 0:58d424fe40b9 285 setupDisplay();
gboggs3 0:58d424fe40b9 286 }
gboggs3 0:58d424fe40b9 287
gboggs3 0:58d424fe40b9 288 //Update life points
gboggs3 0:58d424fe40b9 289 updateLifeBar();
gboggs3 0:58d424fe40b9 290
gboggs3 0:58d424fe40b9 291 //Calculate respective positions and draw accordingly if notes
gboggs3 0:58d424fe40b9 292 //are going on or off screen.
gboggs3 0:58d424fe40b9 293 calculateNoteDims(gNote, gDims);
gboggs3 0:58d424fe40b9 294 calculateNoteDims(rNote, rDims);
gboggs3 0:58d424fe40b9 295 calculateNoteDims(yNote, yDims);
gboggs3 0:58d424fe40b9 296 calculateNoteDims(bNote, bDims);
gboggs3 0:58d424fe40b9 297
gboggs3 0:58d424fe40b9 298 //Draw the notes and erase old positions
gboggs3 0:58d424fe40b9 299 if(gNote[1] >= 0 && gNote[1] < MISS)
gboggs3 0:58d424fe40b9 300 {
gboggs3 0:58d424fe40b9 301 if(gHit)
gboggs3 0:58d424fe40b9 302 {
gboggs3 0:58d424fe40b9 303 gHit = false;
gboggs3 0:58d424fe40b9 304 uLCD.filled_rectangle(gNote[0],gNote[1]-SPEED,gNote[0]+NOTE_WIDTH-1,gNote[1]-1,BLACK);
gboggs3 0:58d424fe40b9 305 uLCD.filled_rectangle(gDims[0],gDims[1],gDims[2],gDims[3],BLACK);
gboggs3 0:58d424fe40b9 306 gNote[1] = -1;
gboggs3 0:58d424fe40b9 307 score += 30;
gboggs3 0:58d424fe40b9 308 combo++;
gboggs3 0:58d424fe40b9 309 hp = (hp + (combo >= 10 ? 10 : combo)) >= 260 ? 260 : (hp + (combo >= 10 ? 10 : combo));
gboggs3 0:58d424fe40b9 310 }
gboggs3 0:58d424fe40b9 311 else
gboggs3 0:58d424fe40b9 312 {
gboggs3 0:58d424fe40b9 313 uLCD.filled_rectangle(gNote[0],gNote[1]-SPEED,gNote[0]+NOTE_WIDTH-1,gNote[1]-1,BLACK);
gboggs3 0:58d424fe40b9 314 uLCD.filled_rectangle(gDims[0],gDims[1],gDims[2],gDims[3],GREEN);
gboggs3 0:58d424fe40b9 315 }
gboggs3 0:58d424fe40b9 316 }
gboggs3 0:58d424fe40b9 317
gboggs3 0:58d424fe40b9 318 if(rNote[1] >= 0 && rNote[1] < MISS)
gboggs3 0:58d424fe40b9 319 {
gboggs3 0:58d424fe40b9 320 if(rHit)
gboggs3 0:58d424fe40b9 321 {
gboggs3 0:58d424fe40b9 322 rHit = false;
gboggs3 0:58d424fe40b9 323 uLCD.filled_rectangle(rNote[0],rNote[1]-SPEED,rNote[0]+NOTE_WIDTH-1,rNote[1]-1,BLACK);
gboggs3 0:58d424fe40b9 324 uLCD.filled_rectangle(rDims[0],rDims[1],rDims[2],rDims[3],BLACK);
gboggs3 0:58d424fe40b9 325 rNote[1] = -1;
gboggs3 0:58d424fe40b9 326 score += 30;
gboggs3 0:58d424fe40b9 327 combo++;
gboggs3 0:58d424fe40b9 328 hp = (hp + (combo >= 10 ? 10 : combo)) >= 260 ? 260 : (hp + (combo >= 10 ? 10 : combo));
gboggs3 0:58d424fe40b9 329 }
gboggs3 0:58d424fe40b9 330 else
gboggs3 0:58d424fe40b9 331 {
gboggs3 0:58d424fe40b9 332 uLCD.filled_rectangle(rNote[0],rNote[1]-SPEED,rNote[0]+NOTE_WIDTH-1,rNote[1]-1,BLACK);
gboggs3 0:58d424fe40b9 333 uLCD.filled_rectangle(rDims[0],rDims[1],rDims[2],rDims[3],RED);
gboggs3 0:58d424fe40b9 334 }
gboggs3 0:58d424fe40b9 335 }
gboggs3 0:58d424fe40b9 336
gboggs3 0:58d424fe40b9 337 if(yNote[1] >= 0 && yNote[1] < MISS)
gboggs3 0:58d424fe40b9 338 {
gboggs3 0:58d424fe40b9 339 if(yHit)
gboggs3 0:58d424fe40b9 340 {
gboggs3 0:58d424fe40b9 341 yHit = false;
gboggs3 0:58d424fe40b9 342 uLCD.filled_rectangle(yNote[0],yNote[1]-SPEED,yNote[0]+NOTE_WIDTH-1,yNote[1]-1,BLACK);
gboggs3 0:58d424fe40b9 343 uLCD.filled_rectangle(yDims[0],yDims[1],yDims[2],yDims[3],BLACK);
gboggs3 0:58d424fe40b9 344 yNote[1] = -1;
gboggs3 0:58d424fe40b9 345 score += 30;
gboggs3 0:58d424fe40b9 346 combo++;
gboggs3 0:58d424fe40b9 347 hp = (hp + (combo >= 10 ? 10 : combo)) >= 260 ? 260 : (hp + (combo >= 10 ? 10 : combo));
gboggs3 0:58d424fe40b9 348 }
gboggs3 0:58d424fe40b9 349 else
gboggs3 0:58d424fe40b9 350 {
gboggs3 0:58d424fe40b9 351 uLCD.filled_rectangle(yNote[0],yNote[1]-SPEED,yNote[0]+NOTE_WIDTH-1,yNote[1]-1,BLACK);
gboggs3 0:58d424fe40b9 352 uLCD.filled_rectangle(yDims[0],yDims[1],yDims[2],yDims[3],YELLOW);
gboggs3 0:58d424fe40b9 353 }
gboggs3 0:58d424fe40b9 354 }
gboggs3 0:58d424fe40b9 355
gboggs3 0:58d424fe40b9 356 if(bNote[1] >= 0 && bNote[1] < MISS)
gboggs3 0:58d424fe40b9 357 {
gboggs3 0:58d424fe40b9 358 if(bHit)
gboggs3 0:58d424fe40b9 359 {
gboggs3 0:58d424fe40b9 360 bHit = false;
gboggs3 0:58d424fe40b9 361 uLCD.filled_rectangle(bNote[0],bNote[1]-SPEED,bNote[0]+NOTE_WIDTH-1,bNote[1]-1,BLACK);
gboggs3 0:58d424fe40b9 362 uLCD.filled_rectangle(bDims[0],bDims[1],bDims[2],bDims[3],BLACK);
gboggs3 0:58d424fe40b9 363 bNote[1] = -1;
gboggs3 0:58d424fe40b9 364 score += 30;
gboggs3 0:58d424fe40b9 365 combo++;
gboggs3 0:58d424fe40b9 366 hp = (hp + (combo >= 10 ? 10 : combo)) >= 260 ? 260 : (hp + (combo >= 10 ? 10 : combo));
gboggs3 0:58d424fe40b9 367 }
gboggs3 0:58d424fe40b9 368 else
gboggs3 0:58d424fe40b9 369 {
gboggs3 0:58d424fe40b9 370 uLCD.filled_rectangle(bNote[0],bNote[1]-SPEED,bNote[0]+NOTE_WIDTH-1,bNote[1]-1,BLACK);
gboggs3 0:58d424fe40b9 371 uLCD.filled_rectangle(bDims[0],bDims[1],bDims[2],bDims[3],BLUE);
gboggs3 0:58d424fe40b9 372 }
gboggs3 0:58d424fe40b9 373
gboggs3 0:58d424fe40b9 374 }
gboggs3 0:58d424fe40b9 375
gboggs3 0:58d424fe40b9 376 //Redraw target boxes at bottom of screen, incase notes are drawn over them
gboggs3 0:58d424fe40b9 377 uLCD.rectangle(0,127-(NOTE_HEIGHT+2),NOTE_WIDTH-1,127,GREEN);
gboggs3 0:58d424fe40b9 378 uLCD.rectangle(NOTE_WIDTH+1,127-(NOTE_HEIGHT+2),2*NOTE_WIDTH,127,RED);
gboggs3 0:58d424fe40b9 379 uLCD.rectangle(2*NOTE_WIDTH+2,127-(NOTE_HEIGHT+2),3*NOTE_WIDTH+1,127,YELLOW);
gboggs3 0:58d424fe40b9 380 uLCD.rectangle(3*NOTE_WIDTH+3,127-(NOTE_HEIGHT+2),4*NOTE_WIDTH+2,127,BLUE);
gboggs3 0:58d424fe40b9 381
gboggs3 0:58d424fe40b9 382 //Check if each note is still on the screen. If it is, increment the position
gboggs3 0:58d424fe40b9 383 gNote[1] = gNote[1] < 0 ? (rand()%100 > 95 ? NOTE_START : -2) : gNote[1] >= MISS ? -1 : (gNote[1] + SPEED);
gboggs3 0:58d424fe40b9 384 if(gNote[1] == -1)
gboggs3 0:58d424fe40b9 385 {
gboggs3 0:58d424fe40b9 386 hp -= 10;
gboggs3 0:58d424fe40b9 387 combo = 0;
gboggs3 0:58d424fe40b9 388 }
gboggs3 0:58d424fe40b9 389 if(gNote[1] == NOTE_START)
gboggs3 0:58d424fe40b9 390 {
gboggs3 0:58d424fe40b9 391 notesCreated++;
gboggs3 0:58d424fe40b9 392 }
gboggs3 0:58d424fe40b9 393
gboggs3 0:58d424fe40b9 394 rNote[1] = rNote[1] < 0 ? (rand()%100 > 95 ? NOTE_START : -2) : rNote[1] >= MISS ? -1 : (rNote[1] + SPEED);
gboggs3 0:58d424fe40b9 395 if(rNote[1] == -1)
gboggs3 0:58d424fe40b9 396 {
gboggs3 0:58d424fe40b9 397 hp -= 10;
gboggs3 0:58d424fe40b9 398 combo = 0;
gboggs3 0:58d424fe40b9 399 }
gboggs3 0:58d424fe40b9 400 if(rNote[1] == NOTE_START)
gboggs3 0:58d424fe40b9 401 {
gboggs3 0:58d424fe40b9 402 notesCreated++;
gboggs3 0:58d424fe40b9 403 }
gboggs3 0:58d424fe40b9 404
gboggs3 0:58d424fe40b9 405 yNote[1] = yNote[1] < 0 ? (rand()%100 > 95 ? NOTE_START : -2) : yNote[1] >= MISS ? -1 : (yNote[1] + SPEED);
gboggs3 0:58d424fe40b9 406 if(yNote[1] == -1)
gboggs3 0:58d424fe40b9 407 {
gboggs3 0:58d424fe40b9 408 hp -= 10;
gboggs3 0:58d424fe40b9 409 combo = 0;
gboggs3 0:58d424fe40b9 410 }
gboggs3 0:58d424fe40b9 411 if(yNote[1] == NOTE_START)
gboggs3 0:58d424fe40b9 412 {
gboggs3 0:58d424fe40b9 413 notesCreated++;
gboggs3 0:58d424fe40b9 414 }
gboggs3 0:58d424fe40b9 415
gboggs3 0:58d424fe40b9 416 bNote[1] = bNote[1] < 0 ? (rand()%100 > 95 ? NOTE_START : -2) : bNote[1] >= MISS ? -1 : (bNote[1] + SPEED);
gboggs3 0:58d424fe40b9 417 if(bNote[1] == -1)
gboggs3 0:58d424fe40b9 418 {
gboggs3 0:58d424fe40b9 419 hp -= 10;
gboggs3 0:58d424fe40b9 420 combo = 0;
gboggs3 0:58d424fe40b9 421 }
gboggs3 0:58d424fe40b9 422 if(bNote[1] == NOTE_START)
gboggs3 0:58d424fe40b9 423 {
gboggs3 0:58d424fe40b9 424 notesCreated++;
gboggs3 0:58d424fe40b9 425 }
gboggs3 0:58d424fe40b9 426
gboggs3 0:58d424fe40b9 427 //Check to make sure HP is above zero, otherwise, Game Over.
gboggs3 0:58d424fe40b9 428 if(hp <= 0)
gboggs3 0:58d424fe40b9 429 gameOver = true;
gboggs3 0:58d424fe40b9 430
gboggs3 0:58d424fe40b9 431 //Check to see if user has won.
gboggs3 0:58d424fe40b9 432 if(notesCreated >= VICTORY_THRESHOLD)
gboggs3 0:58d424fe40b9 433 victory = true;
gboggs3 0:58d424fe40b9 434
gboggs3 0:58d424fe40b9 435 uLCD.locate(0,0);
gboggs3 0:58d424fe40b9 436 uLCD.printf("SCORE: %d\nCOMBO: %d",score,combo);
gboggs3 0:58d424fe40b9 437 }
gboggs3 0:58d424fe40b9 438 else if(gameOver)
gboggs3 0:58d424fe40b9 439 {
gboggs3 0:58d424fe40b9 440 //Sets up the display for a game over.
gboggs3 0:58d424fe40b9 441 uLCD.cls();
gboggs3 0:58d424fe40b9 442 uLCD.background_color(BLACK);
gboggs3 0:58d424fe40b9 443 uLCD.text_width(2);
gboggs3 0:58d424fe40b9 444 uLCD.text_height(2);
gboggs3 0:58d424fe40b9 445 uLCD.locate(0,0);
gboggs3 0:58d424fe40b9 446 uLCD.printf("\n\nGAME OVER");
gboggs3 0:58d424fe40b9 447 uLCD.locate(0,6);
gboggs3 0:58d424fe40b9 448 uLCD.text_width(1.5);
gboggs3 0:58d424fe40b9 449 uLCD.text_height(1.5);
gboggs3 0:58d424fe40b9 450 uLCD.printf("\n\r Score: %d\n\r Combo: %d",score,combo);
gboggs3 0:58d424fe40b9 451 uLCD.text_width(1);
gboggs3 0:58d424fe40b9 452 uLCD.text_height(1);
gboggs3 0:58d424fe40b9 453 uLCD.locate(0,11);
gboggs3 0:58d424fe40b9 454 uLCD.printf("\n\r Strum to reset");
gboggs3 0:58d424fe40b9 455 uLCD.locate(0,0);
gboggs3 0:58d424fe40b9 456 while(gameOver)
gboggs3 0:58d424fe40b9 457 {
gboggs3 0:58d424fe40b9 458 wait(0.1);
gboggs3 0:58d424fe40b9 459 }
gboggs3 0:58d424fe40b9 460 }
gboggs3 0:58d424fe40b9 461 else if(victory)
gboggs3 0:58d424fe40b9 462 {
gboggs3 0:58d424fe40b9 463 //Sets up the display for a victory.
gboggs3 0:58d424fe40b9 464 uLCD.cls();
gboggs3 0:58d424fe40b9 465 uLCD.background_color(BLACK);
gboggs3 0:58d424fe40b9 466 uLCD.text_width(2);
gboggs3 0:58d424fe40b9 467 uLCD.text_height(2);
gboggs3 0:58d424fe40b9 468 uLCD.locate(0,0);
gboggs3 0:58d424fe40b9 469 uLCD.printf("\n\nYOU ROCK!");
gboggs3 0:58d424fe40b9 470 uLCD.locate(0,6);
gboggs3 0:58d424fe40b9 471 uLCD.text_width(1.5);
gboggs3 0:58d424fe40b9 472 uLCD.text_height(1.5);
gboggs3 0:58d424fe40b9 473 uLCD.printf("\n\r Score: %d\n\r Combo: %d",score,combo);
gboggs3 0:58d424fe40b9 474 uLCD.text_width(1);
gboggs3 0:58d424fe40b9 475 uLCD.text_height(1);
gboggs3 0:58d424fe40b9 476 uLCD.locate(0,11);
gboggs3 0:58d424fe40b9 477 uLCD.printf("\n\r Strum to reset");
gboggs3 0:58d424fe40b9 478 uLCD.locate(0,0);
gboggs3 0:58d424fe40b9 479 while(victory)
gboggs3 0:58d424fe40b9 480 {
gboggs3 0:58d424fe40b9 481 wait(0.1);
gboggs3 0:58d424fe40b9 482 }
gboggs3 0:58d424fe40b9 483 }
gboggs3 0:58d424fe40b9 484 else
gboggs3 0:58d424fe40b9 485 {
gboggs3 0:58d424fe40b9 486 //Sets up the display for a paused game.
gboggs3 0:58d424fe40b9 487 uLCD.cls();
gboggs3 0:58d424fe40b9 488 uLCD.background_color(BLACK);
gboggs3 0:58d424fe40b9 489 uLCD.text_width(2);
gboggs3 0:58d424fe40b9 490 uLCD.text_height(2);
gboggs3 0:58d424fe40b9 491 uLCD.locate(0,0);
gboggs3 0:58d424fe40b9 492 uLCD.printf("\n\n\n PAUSED!");
gboggs3 0:58d424fe40b9 493 uLCD.text_width(1);
gboggs3 0:58d424fe40b9 494 uLCD.text_height(1);
gboggs3 0:58d424fe40b9 495 uLCD.locate(0,0);
gboggs3 0:58d424fe40b9 496 while(paused)
gboggs3 0:58d424fe40b9 497 {
gboggs3 0:58d424fe40b9 498 wait(0.1);
gboggs3 0:58d424fe40b9 499 }
gboggs3 0:58d424fe40b9 500 }
gboggs3 0:58d424fe40b9 501 }
gboggs3 0:58d424fe40b9 502 }
gboggs3 0:58d424fe40b9 503
gboggs3 0:58d424fe40b9 504 int main()
gboggs3 0:58d424fe40b9 505 {
gboggs3 0:58d424fe40b9 506 //Intialize display to show game UI
gboggs3 0:58d424fe40b9 507 setupDisplay();
gboggs3 0:58d424fe40b9 508
gboggs3 0:58d424fe40b9 509 //Initialize the strum interrupt to act on a rising edge
gboggs3 0:58d424fe40b9 510 interruptStrum.rise(&strumInterrupt);
gboggs3 0:58d424fe40b9 511
gboggs3 0:58d424fe40b9 512 //Initialize the pause interrupt
gboggs3 0:58d424fe40b9 513 interruptPause.rise(&pauseGame);
gboggs3 0:58d424fe40b9 514
gboggs3 0:58d424fe40b9 515 //Initialize game loop
gboggs3 0:58d424fe40b9 516 Thread gl(playGame);
gboggs3 0:58d424fe40b9 517
gboggs3 0:58d424fe40b9 518 //Play the song
gboggs3 0:58d424fe40b9 519 FILE *fp = fopen("/sd/sound/smoke_on_the_water.wav", "r");
gboggs3 0:58d424fe40b9 520 if(fp == NULL)
gboggs3 0:58d424fe40b9 521 {
gboggs3 0:58d424fe40b9 522 pc.printf("SD Card could not be read!");
gboggs3 0:58d424fe40b9 523 }
gboggs3 0:58d424fe40b9 524 else
gboggs3 0:58d424fe40b9 525 {
gboggs3 0:58d424fe40b9 526 // player.play(fp);
gboggs3 0:58d424fe40b9 527 fclose(fp);
gboggs3 0:58d424fe40b9 528 }
gboggs3 0:58d424fe40b9 529
gboggs3 0:58d424fe40b9 530 //Tasks for main loop (mainly debugging)
gboggs3 0:58d424fe40b9 531 while(1)
gboggs3 0:58d424fe40b9 532 { }
gboggs3 0:58d424fe40b9 533 }