A simple game
Dependencies: 4DGL-uLCD-SE mbed-rtos mbed
Fork of rtos_signals by
main.cpp@4:2bb5deb83b81, 2016-11-04 (annotated)
- 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?
User | Revision | Line number | New 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 | } |