A simple game

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

Fork of rtos_signals by mbed official

Committer:
gmiles3
Date:
Fri Nov 04 13:45:06 2016 +0000
Revision:
4:2bb5deb83b81
Parent:
1:6a8fcc666593
Initial commit for angry balls game

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emilmont 1:6a8fcc666593 1 #include "mbed.h"
emilmont 1:6a8fcc666593 2 #include "rtos.h"
gmiles3 4:2bb5deb83b81 3 #include <mpr121.h>
gmiles3 4:2bb5deb83b81 4 #include "uLCD_4DGL.h"
gmiles3 4:2bb5deb83b81 5 #include "Speaker.h"
emilmont 1:6a8fcc666593 6
gmiles3 4:2bb5deb83b81 7 uLCD_4DGL uLCD(p9,p10,p11);
gmiles3 4:2bb5deb83b81 8 int curr_x_u, curr_y_u, old_x_u, old_y_u; //user's current and old x,y coordinates
gmiles3 4:2bb5deb83b81 9 int curr_x_e, curr_y_e, old_x_e, old_y_e; //enemy's current and old x,y coordinates
gmiles3 4:2bb5deb83b81 10 float dx_e, dy_e, fx_e, fy_e; //x,y velocity of enemy and floating point representation of x,y coordinates
gmiles3 4:2bb5deb83b81 11 int curr_x_b, curr_y_b, old_x_b, old_y_b; //payload's current and old x,y coordinates
gmiles3 4:2bb5deb83b81 12 int curr_x_p, curr_y_p, old_x_p, old_y_p; //portal's current and old x,y coordinates
gmiles3 4:2bb5deb83b81 13 Mutex lcd_mutex;
gmiles3 4:2bb5deb83b81 14
gmiles3 4:2bb5deb83b81 15 Thread box; //handles user-payload collision logic
gmiles3 4:2bb5deb83b81 16 Thread portal; //handles portal logic
gmiles3 4:2bb5deb83b81 17
gmiles3 4:2bb5deb83b81 18 Speaker amp(p21);
gmiles3 4:2bb5deb83b81 19
gmiles3 4:2bb5deb83b81 20 Serial pc(USBTX, USBRX); //debugging
gmiles3 4:2bb5deb83b81 21
gmiles3 4:2bb5deb83b81 22 InterruptIn interrupt(p26);
gmiles3 4:2bb5deb83b81 23 I2C i2c(p28, p27);
gmiles3 4:2bb5deb83b81 24 Mpr121 mpr121(&i2c, Mpr121::ADD_VSS);
gmiles3 4:2bb5deb83b81 25
gmiles3 4:2bb5deb83b81 26 int score = 0;
gmiles3 4:2bb5deb83b81 27 int oldscore = 0;
gmiles3 4:2bb5deb83b81 28
gmiles3 4:2bb5deb83b81 29 volatile int key = -1; //key pressed from keypad; set via interrupts -> volatile so compiler doesn't optimize out value reads
gmiles3 4:2bb5deb83b81 30
gmiles3 4:2bb5deb83b81 31 enum State { START, LIVE, PAUSE, DEAD }; //game status
gmiles3 4:2bb5deb83b81 32 volatile State s = START;
gmiles3 4:2bb5deb83b81 33
gmiles3 4:2bb5deb83b81 34 //interrupt method that runs when keypad has a new value
gmiles3 4:2bb5deb83b81 35 void fallInterrupt() {
gmiles3 4:2bb5deb83b81 36 int key_code=0;
gmiles3 4:2bb5deb83b81 37 int i=0;
gmiles3 4:2bb5deb83b81 38 int value=mpr121.read(0x00);
gmiles3 4:2bb5deb83b81 39 value +=mpr121.read(0x01)<<8;
gmiles3 4:2bb5deb83b81 40 i=0;
gmiles3 4:2bb5deb83b81 41 for (i=0; i<12; i++) {
gmiles3 4:2bb5deb83b81 42 if (((value>>i)&0x01)==1) key_code=i+1;
gmiles3 4:2bb5deb83b81 43 }
gmiles3 4:2bb5deb83b81 44 key = key_code;
gmiles3 4:2bb5deb83b81 45 }
gmiles3 4:2bb5deb83b81 46
gmiles3 4:2bb5deb83b81 47 //handles portal logic
gmiles3 4:2bb5deb83b81 48 void portal_thread() {
gmiles3 4:2bb5deb83b81 49 while(s == LIVE || s == PAUSE) {
gmiles3 4:2bb5deb83b81 50 while(s == PAUSE);
gmiles3 4:2bb5deb83b81 51 //if payload and portal collide, score a point and randomize portal location
gmiles3 4:2bb5deb83b81 52 if (((curr_x_p-3 <= curr_x_b+3 && curr_x_p >= curr_x_b) || (curr_x_p+3 >= curr_x_b-3 && curr_x_p <= curr_x_b)) && ((curr_y_p+3 >= curr_y_b-3 && curr_y_p <= curr_y_b) || (curr_y_p-3 <= curr_y_b+3 && curr_y_p >= curr_y_b))) {
gmiles3 4:2bb5deb83b81 53 score++;
gmiles3 4:2bb5deb83b81 54 curr_x_p = (rand() % 106) + 10;
gmiles3 4:2bb5deb83b81 55 curr_y_p = (rand() % 106) + 10;
gmiles3 4:2bb5deb83b81 56 } else if (((curr_y_p-3 <= curr_y_b+3 && curr_y_p >= curr_y_b) || (curr_y_p+3 >= curr_y_b-3 && curr_y_p <= curr_y_b)) && ((curr_x_p+3 >= curr_x_b-3 && curr_x_p <= curr_x_b) || (curr_x_p-3 <= curr_x_b+3 && curr_x_p >= curr_x_b))) {
gmiles3 4:2bb5deb83b81 57 score++;
gmiles3 4:2bb5deb83b81 58 curr_x_p = (rand() % 106) + 10;
gmiles3 4:2bb5deb83b81 59 curr_y_p = (rand() % 106) + 10;
gmiles3 4:2bb5deb83b81 60 }
gmiles3 4:2bb5deb83b81 61 lcd_mutex.lock();
gmiles3 4:2bb5deb83b81 62 //redraw portal and play note if score has changed
gmiles3 4:2bb5deb83b81 63 uLCD.rectangle(curr_x_p-5, curr_y_p-5, curr_x_p+5, curr_y_p+5, BLUE);
gmiles3 4:2bb5deb83b81 64 if (score != oldscore) {
gmiles3 4:2bb5deb83b81 65 amp.PlayNote(1000.0,0.025,0.5);
gmiles3 4:2bb5deb83b81 66 oldscore = score;
gmiles3 4:2bb5deb83b81 67 uLCD.rectangle(old_x_p-5, old_y_p-5, old_x_p+5, old_y_p+5, BLACK);
gmiles3 4:2bb5deb83b81 68 old_x_p = curr_x_p;
gmiles3 4:2bb5deb83b81 69 old_y_p = curr_y_p;
gmiles3 4:2bb5deb83b81 70 }
gmiles3 4:2bb5deb83b81 71 //print score
gmiles3 4:2bb5deb83b81 72 uLCD.locate(1,15);
gmiles3 4:2bb5deb83b81 73 uLCD.color(0xFF00FF);
gmiles3 4:2bb5deb83b81 74 uLCD.printf("%d", score);
gmiles3 4:2bb5deb83b81 75 lcd_mutex.unlock();
gmiles3 4:2bb5deb83b81 76 }
gmiles3 4:2bb5deb83b81 77 }
emilmont 1:6a8fcc666593 78
gmiles3 4:2bb5deb83b81 79 //handles user-payload collisions
gmiles3 4:2bb5deb83b81 80 void box_thread() {
gmiles3 4:2bb5deb83b81 81 while(s == LIVE) {
gmiles3 4:2bb5deb83b81 82 old_x_u = curr_x_u;
gmiles3 4:2bb5deb83b81 83 old_y_u = curr_y_u;
gmiles3 4:2bb5deb83b81 84 old_x_b = curr_x_b;
gmiles3 4:2bb5deb83b81 85 old_y_b = curr_y_b;
gmiles3 4:2bb5deb83b81 86 //if 3 pressed, then go into pause state
gmiles3 4:2bb5deb83b81 87 if (key==3+1) {
gmiles3 4:2bb5deb83b81 88 s = PAUSE;
gmiles3 4:2bb5deb83b81 89 lcd_mutex.lock();
gmiles3 4:2bb5deb83b81 90 uLCD.locate(1, 2);
gmiles3 4:2bb5deb83b81 91 uLCD.color(0xFFFF00);
gmiles3 4:2bb5deb83b81 92 uLCD.printf("PAUSE");
gmiles3 4:2bb5deb83b81 93 //wait until 3 is unpressed
gmiles3 4:2bb5deb83b81 94 while(key==3+1);
gmiles3 4:2bb5deb83b81 95 //wait until 3 is pressed
gmiles3 4:2bb5deb83b81 96 while(key!=3+1);
gmiles3 4:2bb5deb83b81 97 //wait until 3 is unpressed
gmiles3 4:2bb5deb83b81 98 while(key==3+1);
gmiles3 4:2bb5deb83b81 99 uLCD.locate(1, 2);
gmiles3 4:2bb5deb83b81 100 uLCD.color(BLACK);
gmiles3 4:2bb5deb83b81 101 uLCD.printf("PAUSE");
gmiles3 4:2bb5deb83b81 102 uLCD.color(WHITE);
gmiles3 4:2bb5deb83b81 103 //countdown from 3
gmiles3 4:2bb5deb83b81 104 for (int i=3; i>=1; i--) {
gmiles3 4:2bb5deb83b81 105 uLCD.locate(1, 2);
gmiles3 4:2bb5deb83b81 106 uLCD.printf("%2D", i);
gmiles3 4:2bb5deb83b81 107 amp.PlayNote(800.0,0.025,0.5);
gmiles3 4:2bb5deb83b81 108 wait(1);
gmiles3 4:2bb5deb83b81 109 }
gmiles3 4:2bb5deb83b81 110 uLCD.locate(1,2);
gmiles3 4:2bb5deb83b81 111 uLCD.color(BLACK);
gmiles3 4:2bb5deb83b81 112 uLCD.printf(" ");
gmiles3 4:2bb5deb83b81 113 lcd_mutex.unlock();
gmiles3 4:2bb5deb83b81 114 //play on
gmiles3 4:2bb5deb83b81 115 s = LIVE;
gmiles3 4:2bb5deb83b81 116 }
gmiles3 4:2bb5deb83b81 117 //really complicated collision logic
gmiles3 4:2bb5deb83b81 118 //basically checks each way the boxes could be colliding based on which key is pressed (which direction user is moving)
gmiles3 4:2bb5deb83b81 119 if (key==0+1) {
gmiles3 4:2bb5deb83b81 120
gmiles3 4:2bb5deb83b81 121 if ((curr_x_b+6 > curr_x_u-6 && curr_x_u > curr_x_b) && ((curr_y_u+6 > curr_y_b-6 && curr_y_u <= curr_y_b) || (curr_y_u-6 < curr_y_b+6 && curr_y_u >= curr_y_b))) {
gmiles3 4:2bb5deb83b81 122 curr_x_b-=1;
gmiles3 4:2bb5deb83b81 123 curr_x_u = curr_x_b+12;
gmiles3 4:2bb5deb83b81 124 if (curr_x_b < 7) {
gmiles3 4:2bb5deb83b81 125 curr_x_b = 25;
gmiles3 4:2bb5deb83b81 126 curr_y_b = 63;
gmiles3 4:2bb5deb83b81 127 }
gmiles3 4:2bb5deb83b81 128 } else {
gmiles3 4:2bb5deb83b81 129 curr_x_u-=1;
gmiles3 4:2bb5deb83b81 130 }
gmiles3 4:2bb5deb83b81 131 if (curr_x_u < 7) curr_x_u = 7;
gmiles3 4:2bb5deb83b81 132 } else if (key==8+1) {
gmiles3 4:2bb5deb83b81 133
gmiles3 4:2bb5deb83b81 134 if ((curr_x_b-6 < curr_x_u+6 && curr_x_u < curr_x_b) && ((curr_y_u+6 > curr_y_b-6 && curr_y_u <= curr_y_b) || (curr_y_u-6 < curr_y_b+6 && curr_y_u >= curr_y_b))) {
gmiles3 4:2bb5deb83b81 135 curr_x_b+=1;
gmiles3 4:2bb5deb83b81 136 curr_x_u = curr_x_b-12;
gmiles3 4:2bb5deb83b81 137 if (curr_x_b > 120) {
gmiles3 4:2bb5deb83b81 138 curr_x_b = 25;
gmiles3 4:2bb5deb83b81 139 curr_y_b = 63;
gmiles3 4:2bb5deb83b81 140 }
gmiles3 4:2bb5deb83b81 141 } else {
gmiles3 4:2bb5deb83b81 142 curr_x_u+=1;
gmiles3 4:2bb5deb83b81 143 }
gmiles3 4:2bb5deb83b81 144 if (curr_x_u > 120) curr_x_u = 120;
gmiles3 4:2bb5deb83b81 145 } else if (key==4+1) {
gmiles3 4:2bb5deb83b81 146
gmiles3 4:2bb5deb83b81 147 if ((curr_y_b-6 < curr_y_u+6 && curr_y_u < curr_y_b) && ((curr_x_u+6 > curr_x_b-6 && curr_x_u <= curr_x_b) || (curr_x_u-6 < curr_x_b+6 && curr_x_u >= curr_x_b))) {
gmiles3 4:2bb5deb83b81 148 curr_y_b+=1;
gmiles3 4:2bb5deb83b81 149 curr_y_u = curr_y_b-12;
gmiles3 4:2bb5deb83b81 150 if (curr_y_b > 120) {
gmiles3 4:2bb5deb83b81 151 curr_x_b = 25;
gmiles3 4:2bb5deb83b81 152 curr_y_b = 63;
gmiles3 4:2bb5deb83b81 153 }
gmiles3 4:2bb5deb83b81 154 } else {
gmiles3 4:2bb5deb83b81 155 curr_y_u+=1;
gmiles3 4:2bb5deb83b81 156 }
gmiles3 4:2bb5deb83b81 157 if (curr_y_u > 120) curr_y_u = 120;
gmiles3 4:2bb5deb83b81 158 } else if (key==5+1) {
gmiles3 4:2bb5deb83b81 159
gmiles3 4:2bb5deb83b81 160 if ((curr_y_b+6 > curr_y_u-6 && curr_y_u > curr_y_b) && ((curr_x_u+6 > curr_x_b-6 && curr_x_u <= curr_x_b) || (curr_x_u-6 < curr_x_b+6 && curr_x_u >= curr_x_b))) {
gmiles3 4:2bb5deb83b81 161 curr_y_b-=1;
gmiles3 4:2bb5deb83b81 162 curr_y_u = curr_y_b+12;
gmiles3 4:2bb5deb83b81 163 if (curr_y_b < 7) {
gmiles3 4:2bb5deb83b81 164 curr_x_b = 25;
gmiles3 4:2bb5deb83b81 165 curr_y_b = 63;
gmiles3 4:2bb5deb83b81 166 }
gmiles3 4:2bb5deb83b81 167 } else {
gmiles3 4:2bb5deb83b81 168 curr_y_u-=1;
gmiles3 4:2bb5deb83b81 169 }
gmiles3 4:2bb5deb83b81 170 if (curr_y_u < 7) curr_y_u = 7;
gmiles3 4:2bb5deb83b81 171 }
gmiles3 4:2bb5deb83b81 172 //redraw user and payload
gmiles3 4:2bb5deb83b81 173 lcd_mutex.lock();
gmiles3 4:2bb5deb83b81 174 uLCD.rectangle(20, 58, 30, 68, WHITE);
gmiles3 4:2bb5deb83b81 175 uLCD.filled_rectangle(old_x_u-5, old_y_u-5, old_x_u+5, old_y_u+5, BLACK);
gmiles3 4:2bb5deb83b81 176 uLCD.filled_rectangle(curr_x_u-5, curr_y_u-5, curr_x_u+5, curr_y_u+5, GREEN);
gmiles3 4:2bb5deb83b81 177 uLCD.filled_rectangle(old_x_b-5, old_y_b-5, old_x_b+5, old_y_b+5, BLACK);
gmiles3 4:2bb5deb83b81 178 uLCD.filled_rectangle(curr_x_b-5, curr_y_b-5, curr_x_b+5, curr_y_b+5, DGREY);
gmiles3 4:2bb5deb83b81 179 lcd_mutex.unlock();
emilmont 1:6a8fcc666593 180 }
emilmont 1:6a8fcc666593 181 }
emilmont 1:6a8fcc666593 182
gmiles3 4:2bb5deb83b81 183 //main thread handles setup of game, angry ball collision logic, gameover, and game resets
gmiles3 4:2bb5deb83b81 184 int main() {
gmiles3 4:2bb5deb83b81 185 //setup keypad interrupts
gmiles3 4:2bb5deb83b81 186 interrupt.fall(&fallInterrupt);
gmiles3 4:2bb5deb83b81 187 interrupt.mode(PullUp);
gmiles3 4:2bb5deb83b81 188 uLCD.baudrate(3000000);
gmiles3 4:2bb5deb83b81 189 //load in Angry Balls image from SD
gmiles3 4:2bb5deb83b81 190 uLCD.media_init();
gmiles3 4:2bb5deb83b81 191 uLCD.set_sector_address(0x003B, 0xD400);
gmiles3 4:2bb5deb83b81 192 uLCD.display_image(0,0);
gmiles3 4:2bb5deb83b81 193 //wait 3 seconds to allow keypad time to set up while player can look at the pretty image
gmiles3 4:2bb5deb83b81 194 wait(3);
gmiles3 4:2bb5deb83b81 195 uLCD.textbackground_color(WHITE);
gmiles3 4:2bb5deb83b81 196 uLCD.text_width(1);
gmiles3 4:2bb5deb83b81 197 uLCD.text_height(1);
gmiles3 4:2bb5deb83b81 198 uLCD.color(RED);
gmiles3 4:2bb5deb83b81 199 uLCD.locate(0, 0);
gmiles3 4:2bb5deb83b81 200 uLCD.printf("Angry Balls!");
gmiles3 4:2bb5deb83b81 201 uLCD.locate(0, 1);
gmiles3 4:2bb5deb83b81 202 uLCD.color(BLACK);
gmiles3 4:2bb5deb83b81 203 uLCD.printf("Press 3 to play");
gmiles3 4:2bb5deb83b81 204 //start tone
gmiles3 4:2bb5deb83b81 205 amp.PlayNote(700.0,0.2,0.5);
gmiles3 4:2bb5deb83b81 206 amp.PlayNote(1000.0,0.2,0.0);
gmiles3 4:2bb5deb83b81 207 amp.PlayNote(600.0,0.1,0.5);
gmiles3 4:2bb5deb83b81 208 amp.PlayNote(1000.0,0.1,0.0);
gmiles3 4:2bb5deb83b81 209 amp.PlayNote(700.0,0.5,0.5);
gmiles3 4:2bb5deb83b81 210 //wait until 3 is pressed
gmiles3 4:2bb5deb83b81 211 while(key != 3+1);
gmiles3 4:2bb5deb83b81 212 //wait until 3 is unpressed
gmiles3 4:2bb5deb83b81 213 while(key == 3+1);
gmiles3 4:2bb5deb83b81 214 //clear screen
gmiles3 4:2bb5deb83b81 215 uLCD.cls();
gmiles3 4:2bb5deb83b81 216 uLCD.textbackground_color(BLACK);
gmiles3 4:2bb5deb83b81 217 uLCD.background_color(BLACK);
gmiles3 4:2bb5deb83b81 218 //setup initial state for every object
gmiles3 4:2bb5deb83b81 219 curr_x_u = 9;
gmiles3 4:2bb5deb83b81 220 curr_y_u = 63;
gmiles3 4:2bb5deb83b81 221 curr_x_b = 25;
gmiles3 4:2bb5deb83b81 222 curr_y_b = 63;
gmiles3 4:2bb5deb83b81 223 curr_x_e = 75;
gmiles3 4:2bb5deb83b81 224 curr_y_e = 75;
gmiles3 4:2bb5deb83b81 225 dx_e = -0.75;
gmiles3 4:2bb5deb83b81 226 dy_e = 0.75;
gmiles3 4:2bb5deb83b81 227 curr_x_p = 110;
gmiles3 4:2bb5deb83b81 228 curr_y_p = 15;
gmiles3 4:2bb5deb83b81 229 old_x_p = curr_x_p;
gmiles3 4:2bb5deb83b81 230 old_y_p = curr_y_p;
gmiles3 4:2bb5deb83b81 231 //draw everything
gmiles3 4:2bb5deb83b81 232 uLCD.filled_rectangle(curr_x_u-5, curr_y_u-5, curr_x_u+5, curr_y_u+5, GREEN);
gmiles3 4:2bb5deb83b81 233 uLCD.filled_rectangle(curr_x_b-5, curr_y_b-5, curr_x_b+5, curr_y_b+5, DGREY);
gmiles3 4:2bb5deb83b81 234 uLCD.filled_circle(curr_x_e, curr_y_e, 6, RED);
gmiles3 4:2bb5deb83b81 235 uLCD.rectangle(curr_x_p-5, curr_y_p-5, curr_x_p+5, curr_y_p+5, BLUE);
gmiles3 4:2bb5deb83b81 236 uLCD.color(WHITE);
gmiles3 4:2bb5deb83b81 237 uLCD.locate(1,2);
gmiles3 4:2bb5deb83b81 238 uLCD.printf("Place ball!");
gmiles3 4:2bb5deb83b81 239 //logic for placing ball before game starts based on key presses; prevents ball from going through walls & middle boundary
gmiles3 4:2bb5deb83b81 240 while(key != 3+1) {
gmiles3 4:2bb5deb83b81 241 old_x_e = curr_x_e;
gmiles3 4:2bb5deb83b81 242 old_y_e = curr_y_e;
gmiles3 4:2bb5deb83b81 243 if (key==0+1) {
gmiles3 4:2bb5deb83b81 244 curr_x_e-=2;
gmiles3 4:2bb5deb83b81 245 if (curr_x_e < 71) curr_x_e = 71;
gmiles3 4:2bb5deb83b81 246 }
gmiles3 4:2bb5deb83b81 247 if (key==8+1) {
gmiles3 4:2bb5deb83b81 248 curr_x_e+=2;
gmiles3 4:2bb5deb83b81 249 if (curr_x_e > 120) curr_x_e = 120;
gmiles3 4:2bb5deb83b81 250 }
gmiles3 4:2bb5deb83b81 251 if (key==4+1) {
gmiles3 4:2bb5deb83b81 252 curr_y_e+=2;
gmiles3 4:2bb5deb83b81 253 if (curr_y_e > 120) curr_y_e = 120;
gmiles3 4:2bb5deb83b81 254 }
gmiles3 4:2bb5deb83b81 255 if (key==5+1) {
gmiles3 4:2bb5deb83b81 256 curr_y_e-=2;
gmiles3 4:2bb5deb83b81 257 if (curr_y_e < 7) curr_y_e = 7;
gmiles3 4:2bb5deb83b81 258 }
gmiles3 4:2bb5deb83b81 259 //draw ball
gmiles3 4:2bb5deb83b81 260 uLCD.locate(1,2);
gmiles3 4:2bb5deb83b81 261 uLCD.printf("Place ball!");
gmiles3 4:2bb5deb83b81 262 uLCD.rectangle(curr_x_p-5, curr_y_p-5, curr_x_p+5, curr_y_p+5, BLUE);
gmiles3 4:2bb5deb83b81 263 uLCD.filled_circle(old_x_e, old_y_e, 6, BLACK);
gmiles3 4:2bb5deb83b81 264 uLCD.filled_circle(curr_x_e, curr_y_e, 6, RED);
gmiles3 4:2bb5deb83b81 265 }
gmiles3 4:2bb5deb83b81 266 //wait until 3 is unpressed
gmiles3 4:2bb5deb83b81 267 while(key==3+1);
gmiles3 4:2bb5deb83b81 268 uLCD.locate(1,2);
gmiles3 4:2bb5deb83b81 269 uLCD.color(BLACK);
gmiles3 4:2bb5deb83b81 270 uLCD.printf("Place ball!");
gmiles3 4:2bb5deb83b81 271 fx_e = curr_x_e;
gmiles3 4:2bb5deb83b81 272 fy_e = curr_y_e;
gmiles3 4:2bb5deb83b81 273 uLCD.color(WHITE);
gmiles3 4:2bb5deb83b81 274 //countdown til start
gmiles3 4:2bb5deb83b81 275 for (int i=3; i>=1; i--) {
gmiles3 4:2bb5deb83b81 276 uLCD.locate(1, 2);
gmiles3 4:2bb5deb83b81 277 uLCD.printf("%2D", i);
gmiles3 4:2bb5deb83b81 278 amp.PlayNote(800.0,0.025,0.5);
gmiles3 4:2bb5deb83b81 279 wait(1);
emilmont 1:6a8fcc666593 280 }
gmiles3 4:2bb5deb83b81 281 uLCD.locate(1,2);
gmiles3 4:2bb5deb83b81 282 uLCD.color(BLACK);
gmiles3 4:2bb5deb83b81 283 uLCD.printf(" ");
gmiles3 4:2bb5deb83b81 284 //game is live, start other two threads
gmiles3 4:2bb5deb83b81 285 s = LIVE;
gmiles3 4:2bb5deb83b81 286 box.start(box_thread);
gmiles3 4:2bb5deb83b81 287 portal.start(portal_thread);
gmiles3 4:2bb5deb83b81 288 //collision logic for angry ball
gmiles3 4:2bb5deb83b81 289 //check if ball has collided with a wall, the user, or the payload (gameover)
gmiles3 4:2bb5deb83b81 290 while(s == LIVE || s == PAUSE) {
gmiles3 4:2bb5deb83b81 291 while (s==PAUSE);
gmiles3 4:2bb5deb83b81 292 old_x_e = curr_x_e;
gmiles3 4:2bb5deb83b81 293 old_y_e = curr_y_e;
gmiles3 4:2bb5deb83b81 294 if (curr_x_e < 7) {
gmiles3 4:2bb5deb83b81 295 curr_x_e = 7;
gmiles3 4:2bb5deb83b81 296 dx_e = -dx_e;
gmiles3 4:2bb5deb83b81 297 } else if (curr_x_e > 120) {
gmiles3 4:2bb5deb83b81 298 curr_x_e = 120;
gmiles3 4:2bb5deb83b81 299 dx_e = -dx_e;
gmiles3 4:2bb5deb83b81 300 } else if (curr_y_e > 120) {
gmiles3 4:2bb5deb83b81 301 curr_y_e = 120;
gmiles3 4:2bb5deb83b81 302 dy_e = -dy_e;
gmiles3 4:2bb5deb83b81 303 } else if (curr_y_e < 7) {
gmiles3 4:2bb5deb83b81 304 curr_y_e = 7;
gmiles3 4:2bb5deb83b81 305 dy_e = -dy_e;
gmiles3 4:2bb5deb83b81 306 } else if (((dx_e < 0 && curr_x_e-6 < curr_x_u+6 && curr_x_e > curr_x_u) || (dx_e > 0 && curr_x_e+6 > curr_x_u-6 && curr_x_e < curr_x_u)) && ((curr_y_e+6 > curr_y_u-6 && curr_y_e < curr_y_u) || (curr_y_e-6 < curr_y_u+6 && curr_y_e > curr_y_u))) {
gmiles3 4:2bb5deb83b81 307 dx_e = -dx_e;
gmiles3 4:2bb5deb83b81 308 } else if (((dy_e < 0 && curr_y_e-6 < curr_y_u+6 && curr_y_e > curr_y_u) || (dy_e > 0 && curr_y_e+6 > curr_y_u-6 && curr_y_e < curr_y_u)) && ((curr_x_e+6 > curr_x_u-6 && curr_x_e < curr_x_u) || (curr_x_e-6 < curr_x_u+6 && curr_x_e > curr_x_u))) {
gmiles3 4:2bb5deb83b81 309 dy_e = -dy_e;
gmiles3 4:2bb5deb83b81 310 }
gmiles3 4:2bb5deb83b81 311 if (((dx_e < 0 && curr_x_e-6 < curr_x_b+6 && curr_x_e > curr_x_b) || (dx_e > 0 && curr_x_e+6 > curr_x_b-6 && curr_x_e < curr_x_b)) && ((curr_y_e+6 > curr_y_b-6 && curr_y_e < curr_y_b) || (curr_y_e-6 < curr_y_b+6 && curr_y_e > curr_y_b))) {
gmiles3 4:2bb5deb83b81 312 s = DEAD;
gmiles3 4:2bb5deb83b81 313 } else if (((dy_e < 0 && curr_y_e-6 < curr_y_b+6 && curr_y_e > curr_y_b) || (dy_e > 0 && curr_y_e+6 > curr_y_b-6 && curr_y_e < curr_y_b)) && ((curr_x_e+6 > curr_x_b-6 && curr_x_e < curr_x_b) || (curr_x_e-6 < curr_x_b+6 && curr_x_e > curr_x_b))) {
gmiles3 4:2bb5deb83b81 314 s = DEAD;
gmiles3 4:2bb5deb83b81 315 }
gmiles3 4:2bb5deb83b81 316 //update floating point coordinates with velocity values
gmiles3 4:2bb5deb83b81 317 fx_e += dx_e;
gmiles3 4:2bb5deb83b81 318 fy_e += dy_e;
gmiles3 4:2bb5deb83b81 319 //cast floating coordinates to integer coordinates
gmiles3 4:2bb5deb83b81 320 curr_x_e = (int) fx_e;
gmiles3 4:2bb5deb83b81 321 curr_y_e = (int) fy_e;
gmiles3 4:2bb5deb83b81 322 //redraw ball
gmiles3 4:2bb5deb83b81 323 lcd_mutex.lock();
gmiles3 4:2bb5deb83b81 324 uLCD.filled_circle(old_x_e, old_y_e, 6, BLACK);
gmiles3 4:2bb5deb83b81 325 uLCD.filled_circle(curr_x_e, curr_y_e, 6, RED);
gmiles3 4:2bb5deb83b81 326 lcd_mutex.unlock();
gmiles3 4:2bb5deb83b81 327 //if ball-payload collision has occurred, game is now dead
gmiles3 4:2bb5deb83b81 328 if (s == DEAD) {
gmiles3 4:2bb5deb83b81 329 //print gameover, score, instructions to start over, and play gameover sound
gmiles3 4:2bb5deb83b81 330 lcd_mutex.lock();
gmiles3 4:2bb5deb83b81 331 uLCD.cls();
gmiles3 4:2bb5deb83b81 332 uLCD.locate(1,2);
gmiles3 4:2bb5deb83b81 333 uLCD.color(RED);
gmiles3 4:2bb5deb83b81 334 uLCD.printf("GAMEOVER");
gmiles3 4:2bb5deb83b81 335 uLCD.locate(1,4);
gmiles3 4:2bb5deb83b81 336 uLCD.color(0x4B0082);
gmiles3 4:2bb5deb83b81 337 uLCD.printf("Score:%d", score);
gmiles3 4:2bb5deb83b81 338 uLCD.locate(1,8);
gmiles3 4:2bb5deb83b81 339 uLCD.color(WHITE);
gmiles3 4:2bb5deb83b81 340 uLCD.printf("Press 3 to retry");
gmiles3 4:2bb5deb83b81 341 amp.PlayNote(300.0,0.5,0.5);
gmiles3 4:2bb5deb83b81 342 amp.PlayNote(300.0,0.05,0.0);
gmiles3 4:2bb5deb83b81 343 amp.PlayNote(280.0,0.5,0.5);
gmiles3 4:2bb5deb83b81 344 amp.PlayNote(300.0,0.05,0.0);
gmiles3 4:2bb5deb83b81 345 amp.PlayNote(260.0,1.0,0.5);
gmiles3 4:2bb5deb83b81 346 //wait until 3 is pressed
gmiles3 4:2bb5deb83b81 347 while(key != 3+1);
gmiles3 4:2bb5deb83b81 348 //wait until 3 is unpressed
gmiles3 4:2bb5deb83b81 349 while(key == 3+1);
gmiles3 4:2bb5deb83b81 350 //reinitialize game state for new game; same code as above
gmiles3 4:2bb5deb83b81 351 uLCD.cls();
gmiles3 4:2bb5deb83b81 352 score = 0;
gmiles3 4:2bb5deb83b81 353 oldscore = 0;
gmiles3 4:2bb5deb83b81 354 curr_x_u = 9;
gmiles3 4:2bb5deb83b81 355 curr_y_u = 63;
gmiles3 4:2bb5deb83b81 356 curr_x_b = 25;
gmiles3 4:2bb5deb83b81 357 curr_y_b = 63;
gmiles3 4:2bb5deb83b81 358 curr_x_e = 75;
gmiles3 4:2bb5deb83b81 359 curr_y_e = 75;
gmiles3 4:2bb5deb83b81 360 dx_e = -0.75;
gmiles3 4:2bb5deb83b81 361 dy_e = 0.75;
gmiles3 4:2bb5deb83b81 362 curr_x_p = 110;
gmiles3 4:2bb5deb83b81 363 curr_y_p = 15;
gmiles3 4:2bb5deb83b81 364 old_x_p = curr_x_p;
gmiles3 4:2bb5deb83b81 365 old_y_p = curr_y_p;
gmiles3 4:2bb5deb83b81 366 uLCD.filled_rectangle(curr_x_u-5, curr_y_u-5, curr_x_u+5, curr_y_u+5, GREEN);
gmiles3 4:2bb5deb83b81 367 uLCD.filled_rectangle(curr_x_b-5, curr_y_b-5, curr_x_b+5, curr_y_b+5, DGREY);
gmiles3 4:2bb5deb83b81 368 uLCD.filled_circle(curr_x_e, curr_y_e, 6, RED);
gmiles3 4:2bb5deb83b81 369 uLCD.rectangle(curr_x_p-5, curr_y_p-5, curr_x_p+5, curr_y_p+5, BLUE);
gmiles3 4:2bb5deb83b81 370 uLCD.color(WHITE);
gmiles3 4:2bb5deb83b81 371 uLCD.locate(1,2);
gmiles3 4:2bb5deb83b81 372 uLCD.printf("Place ball!");
gmiles3 4:2bb5deb83b81 373 while(key != 3+1) {
gmiles3 4:2bb5deb83b81 374 old_x_e = curr_x_e;
gmiles3 4:2bb5deb83b81 375 old_y_e = curr_y_e;
gmiles3 4:2bb5deb83b81 376 if (key==0+1) {
gmiles3 4:2bb5deb83b81 377 curr_x_e-=2;
gmiles3 4:2bb5deb83b81 378 if (curr_x_e < 71) curr_x_e = 71;
gmiles3 4:2bb5deb83b81 379 }
gmiles3 4:2bb5deb83b81 380 if (key==8+1) {
gmiles3 4:2bb5deb83b81 381 curr_x_e+=2;
gmiles3 4:2bb5deb83b81 382 if (curr_x_e > 120) curr_x_e = 120;
gmiles3 4:2bb5deb83b81 383 }
gmiles3 4:2bb5deb83b81 384 if (key==4+1) {
gmiles3 4:2bb5deb83b81 385 curr_y_e+=2;
gmiles3 4:2bb5deb83b81 386 if (curr_y_e > 120) curr_y_e = 120;
gmiles3 4:2bb5deb83b81 387 }
gmiles3 4:2bb5deb83b81 388 if (key==5+1) {
gmiles3 4:2bb5deb83b81 389 curr_y_e-=2;
gmiles3 4:2bb5deb83b81 390 if (curr_y_e < 7) curr_y_e = 7;
gmiles3 4:2bb5deb83b81 391 }
gmiles3 4:2bb5deb83b81 392 uLCD.locate(1,2);
gmiles3 4:2bb5deb83b81 393 uLCD.printf("Place ball!");
gmiles3 4:2bb5deb83b81 394 uLCD.rectangle(curr_x_p-5, curr_y_p-5, curr_x_p+5, curr_y_p+5, BLUE);
gmiles3 4:2bb5deb83b81 395 uLCD.filled_circle(old_x_e, old_y_e, 6, BLACK);
gmiles3 4:2bb5deb83b81 396 uLCD.filled_circle(curr_x_e, curr_y_e, 6, RED);
gmiles3 4:2bb5deb83b81 397 }
gmiles3 4:2bb5deb83b81 398 while(key==3+1);
gmiles3 4:2bb5deb83b81 399 uLCD.locate(1,2);
gmiles3 4:2bb5deb83b81 400 uLCD.color(BLACK);
gmiles3 4:2bb5deb83b81 401 uLCD.printf("Place ball!");
gmiles3 4:2bb5deb83b81 402 fx_e = curr_x_e;
gmiles3 4:2bb5deb83b81 403 fy_e = curr_y_e;
gmiles3 4:2bb5deb83b81 404 uLCD.color(WHITE);
gmiles3 4:2bb5deb83b81 405 for (int i=3; i>=1; i--) {
gmiles3 4:2bb5deb83b81 406 uLCD.locate(1, 2);
gmiles3 4:2bb5deb83b81 407 uLCD.printf("%2D", i);
gmiles3 4:2bb5deb83b81 408 amp.PlayNote(800.0,0.025,0.5);
gmiles3 4:2bb5deb83b81 409 wait(1);
gmiles3 4:2bb5deb83b81 410 }
gmiles3 4:2bb5deb83b81 411 uLCD.locate(1,2);
gmiles3 4:2bb5deb83b81 412 uLCD.color(BLACK);
gmiles3 4:2bb5deb83b81 413 uLCD.printf(" ");
gmiles3 4:2bb5deb83b81 414 lcd_mutex.unlock();
gmiles3 4:2bb5deb83b81 415 //game is live again
gmiles3 4:2bb5deb83b81 416 //restart the other threads
gmiles3 4:2bb5deb83b81 417 s = LIVE;
gmiles3 4:2bb5deb83b81 418 box.start(box_thread);
gmiles3 4:2bb5deb83b81 419 portal.start(portal_thread);
gmiles3 4:2bb5deb83b81 420 }
gmiles3 4:2bb5deb83b81 421 }
gmiles3 4:2bb5deb83b81 422 }