Mini project
Dependencies: 4DGL-uLCD-SE mbed-rtos mbed
main.cpp@0:5cab8e2cf6a9, 2015-10-21 (annotated)
- Committer:
- rollschild
- Date:
- Wed Oct 21 18:55:08 2015 +0000
- Revision:
- 0:5cab8e2cf6a9
...
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rollschild | 0:5cab8e2cf6a9 | 1 | |
rollschild | 0:5cab8e2cf6a9 | 2 | #include "mbed.h" |
rollschild | 0:5cab8e2cf6a9 | 3 | #include "rtos.h" |
rollschild | 0:5cab8e2cf6a9 | 4 | #include "uLCD_4DGL.h" |
rollschild | 0:5cab8e2cf6a9 | 5 | |
rollschild | 0:5cab8e2cf6a9 | 6 | #define PAC_SIZE 5 //The radius of Pacman and the ghost |
rollschild | 0:5cab8e2cf6a9 | 7 | #define STEP_SIZE 8 //The number of pixels each character moves at once |
rollschild | 0:5cab8e2cf6a9 | 8 | #define CLEARANCE 12 //The number of pixels each character checks ahead before moving |
rollschild | 0:5cab8e2cf6a9 | 9 | |
rollschild | 0:5cab8e2cf6a9 | 10 | DigitalIn left_pb(p21); // push button |
rollschild | 0:5cab8e2cf6a9 | 11 | DigitalIn right_pb(p22); // push button |
rollschild | 0:5cab8e2cf6a9 | 12 | DigitalIn up_pb(p23); // push button |
rollschild | 0:5cab8e2cf6a9 | 13 | DigitalIn down_pb(p24); // push button |
rollschild | 0:5cab8e2cf6a9 | 14 | |
rollschild | 0:5cab8e2cf6a9 | 15 | /* |
rollschild | 0:5cab8e2cf6a9 | 16 | AnalogIn jsx(p19); // The joysticks origin is about 1.6V in both directions |
rollschild | 0:5cab8e2cf6a9 | 17 | AnalogIn jsy(p20); // For just three states in each direction, thresholds .33V and 3V were used |
rollschild | 0:5cab8e2cf6a9 | 18 | */ |
rollschild | 0:5cab8e2cf6a9 | 19 | |
rollschild | 0:5cab8e2cf6a9 | 20 | uLCD_4DGL uLCD(p28, p27, p29); |
rollschild | 0:5cab8e2cf6a9 | 21 | Mutex lcd_mutex; |
rollschild | 0:5cab8e2cf6a9 | 22 | |
rollschild | 0:5cab8e2cf6a9 | 23 | void checkMOVE(void); //This function is defined below. It was written here since other functions return to it that it also calls. |
rollschild | 0:5cab8e2cf6a9 | 24 | |
rollschild | 0:5cab8e2cf6a9 | 25 | //several variables are used by multiple threads |
rollschild | 0:5cab8e2cf6a9 | 26 | volatile bool win = false; //True when pacman has eaten all coins |
rollschild | 0:5cab8e2cf6a9 | 27 | volatile bool lose = false; //True when the position of the ghost and pacman are the same |
rollschild | 0:5cab8e2cf6a9 | 28 | volatile int x = 64; //x and y are pacman's position. The starting position is defined here. |
rollschild | 0:5cab8e2cf6a9 | 29 | volatile int y = 88; |
rollschild | 0:5cab8e2cf6a9 | 30 | volatile int gx1 = 64; //Starting position of the blue ghost |
rollschild | 0:5cab8e2cf6a9 | 31 | volatile int gy1 = 40; |
rollschild | 0:5cab8e2cf6a9 | 32 | int i; |
rollschild | 0:5cab8e2cf6a9 | 33 | bool clearRIGHT, clearLEFT, clearUP, clearDOWN, bgcr, bgcl, bgcu, bgcd; |
rollschild | 0:5cab8e2cf6a9 | 34 | |
rollschild | 0:5cab8e2cf6a9 | 35 | //An array containing the locations of the 81 coins pacman must eat |
rollschild | 0:5cab8e2cf6a9 | 36 | int coins[81][2] = { |
rollschild | 0:5cab8e2cf6a9 | 37 | {40,88},{48,88},{56,88},{72,88},{80,88},{88,88}, |
rollschild | 0:5cab8e2cf6a9 | 38 | {40,40},{48,40},{56,40},{64,40},{72,40},{80,40},{88,40}, |
rollschild | 0:5cab8e2cf6a9 | 39 | {40,48},{40,56},{40,64},{40,72},{40,80}, |
rollschild | 0:5cab8e2cf6a9 | 40 | {88,48},{88,56},{88,64},{88,72},{88,80}, |
rollschild | 0:5cab8e2cf6a9 | 41 | {56,96},{56,104},{56,112}, |
rollschild | 0:5cab8e2cf6a9 | 42 | {48,112},{40,112},{32,112},{24,112},{16,112}, |
rollschild | 0:5cab8e2cf6a9 | 43 | {16,104},{16,96},{16,88},{16,80},{16,72}, |
rollschild | 0:5cab8e2cf6a9 | 44 | {24,64},{32,64}, |
rollschild | 0:5cab8e2cf6a9 | 45 | {16,64},{16,56},{16,48},{16,40},{16,32},{16,24},{16,16}, |
rollschild | 0:5cab8e2cf6a9 | 46 | {24,16},{32,16},{40,16},{48,16},{56,16}, |
rollschild | 0:5cab8e2cf6a9 | 47 | {56,24},{56,32}, |
rollschild | 0:5cab8e2cf6a9 | 48 | {72,96},{72,104},{72,112}, |
rollschild | 0:5cab8e2cf6a9 | 49 | {80,112},{88,112},{96,112},{104,112},{112,112}, |
rollschild | 0:5cab8e2cf6a9 | 50 | {112,104},{112,96},{112,88},{112,80},{112,72}, |
rollschild | 0:5cab8e2cf6a9 | 51 | {104,64},{96,64}, |
rollschild | 0:5cab8e2cf6a9 | 52 | {112,64},{112,56},{112,48},{112,40},{112,32},{112,24},{112,16}, |
rollschild | 0:5cab8e2cf6a9 | 53 | {104,16},{96,16},{88,16},{80,16},{72,16}, |
rollschild | 0:5cab8e2cf6a9 | 54 | {72,24},{72,32} |
rollschild | 0:5cab8e2cf6a9 | 55 | }; |
rollschild | 0:5cab8e2cf6a9 | 56 | |
rollschild | 0:5cab8e2cf6a9 | 57 | //This function is used in the ghost thread to replace coins as it passes over them |
rollschild | 0:5cab8e2cf6a9 | 58 | void replaceCOINS(void) |
rollschild | 0:5cab8e2cf6a9 | 59 | { |
rollschild | 0:5cab8e2cf6a9 | 60 | for(int n=0; n<81; n++) { |
rollschild | 0:5cab8e2cf6a9 | 61 | lcd_mutex.lock(); //The coins array is used by both threads |
rollschild | 0:5cab8e2cf6a9 | 62 | if(gx1 == coins[n][0] && gy1 == coins[n][1]) { |
rollschild | 0:5cab8e2cf6a9 | 63 | uLCD.filled_circle(gx1,gy1,1,0xFFFF00); //compare the set of coins to the ghost's previous position and if there is a match redraw coin |
rollschild | 0:5cab8e2cf6a9 | 64 | } |
rollschild | 0:5cab8e2cf6a9 | 65 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 66 | } |
rollschild | 0:5cab8e2cf6a9 | 67 | } |
rollschild | 0:5cab8e2cf6a9 | 68 | |
rollschild | 0:5cab8e2cf6a9 | 69 | //Checks if the ghost can move right (there is no boundary immediately to the right) |
rollschild | 0:5cab8e2cf6a9 | 70 | void BGclearRIGHT(void) |
rollschild | 0:5cab8e2cf6a9 | 71 | { |
rollschild | 0:5cab8e2cf6a9 | 72 | bgcr = true; |
rollschild | 0:5cab8e2cf6a9 | 73 | for(int p=gx1; p <= gx1+CLEARANCE; p++) { |
rollschild | 0:5cab8e2cf6a9 | 74 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 75 | if(uLCD.read_pixel(p,gy1)==uLCD.read_pixel(4,4)) { |
rollschild | 0:5cab8e2cf6a9 | 76 | bgcr = false; //compare the pixels immediately in front of the ghost to the boundary up to the spec. clearance |
rollschild | 0:5cab8e2cf6a9 | 77 | } //if they are the same color, determine the ghost can't move right |
rollschild | 0:5cab8e2cf6a9 | 78 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 79 | } |
rollschild | 0:5cab8e2cf6a9 | 80 | } |
rollschild | 0:5cab8e2cf6a9 | 81 | |
rollschild | 0:5cab8e2cf6a9 | 82 | //Checks if ghost can move left |
rollschild | 0:5cab8e2cf6a9 | 83 | void BGclearLEFT(void) |
rollschild | 0:5cab8e2cf6a9 | 84 | { |
rollschild | 0:5cab8e2cf6a9 | 85 | bgcl = true; |
rollschild | 0:5cab8e2cf6a9 | 86 | for(int p=gx1; p >= gx1-CLEARANCE; p--) { |
rollschild | 0:5cab8e2cf6a9 | 87 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 88 | if(uLCD.read_pixel(p,gy1)==uLCD.read_pixel(4,4)) { |
rollschild | 0:5cab8e2cf6a9 | 89 | bgcl = false; |
rollschild | 0:5cab8e2cf6a9 | 90 | } |
rollschild | 0:5cab8e2cf6a9 | 91 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 92 | } |
rollschild | 0:5cab8e2cf6a9 | 93 | } |
rollschild | 0:5cab8e2cf6a9 | 94 | |
rollschild | 0:5cab8e2cf6a9 | 95 | //Checks if ghost can move up |
rollschild | 0:5cab8e2cf6a9 | 96 | void BGclearUP(void) |
rollschild | 0:5cab8e2cf6a9 | 97 | { |
rollschild | 0:5cab8e2cf6a9 | 98 | bgcu = true; |
rollschild | 0:5cab8e2cf6a9 | 99 | for(int p=gy1; p >= gy1-CLEARANCE; p--) { |
rollschild | 0:5cab8e2cf6a9 | 100 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 101 | if(uLCD.read_pixel(gx1,p)==uLCD.read_pixel(4,4)) { |
rollschild | 0:5cab8e2cf6a9 | 102 | bgcu = false; |
rollschild | 0:5cab8e2cf6a9 | 103 | } |
rollschild | 0:5cab8e2cf6a9 | 104 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 105 | } |
rollschild | 0:5cab8e2cf6a9 | 106 | } |
rollschild | 0:5cab8e2cf6a9 | 107 | |
rollschild | 0:5cab8e2cf6a9 | 108 | //Checks if ghost can move down |
rollschild | 0:5cab8e2cf6a9 | 109 | void BGclearDOWN(void) |
rollschild | 0:5cab8e2cf6a9 | 110 | { |
rollschild | 0:5cab8e2cf6a9 | 111 | bgcd = true; |
rollschild | 0:5cab8e2cf6a9 | 112 | for(int p=gy1; p <= gy1+CLEARANCE; p++) { |
rollschild | 0:5cab8e2cf6a9 | 113 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 114 | if(uLCD.read_pixel(gx1,p)==uLCD.read_pixel(4,4)) { |
rollschild | 0:5cab8e2cf6a9 | 115 | bgcd = false; |
rollschild | 0:5cab8e2cf6a9 | 116 | } |
rollschild | 0:5cab8e2cf6a9 | 117 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 118 | } |
rollschild | 0:5cab8e2cf6a9 | 119 | } |
rollschild | 0:5cab8e2cf6a9 | 120 | |
rollschild | 0:5cab8e2cf6a9 | 121 | //Moves the blue ghost to the right |
rollschild | 0:5cab8e2cf6a9 | 122 | void bgRIGHT(void) |
rollschild | 0:5cab8e2cf6a9 | 123 | { |
rollschild | 0:5cab8e2cf6a9 | 124 | Thread::wait(50); |
rollschild | 0:5cab8e2cf6a9 | 125 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 126 | uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK); //erase the previous ghost drawing |
rollschild | 0:5cab8e2cf6a9 | 127 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 128 | replaceCOINS(); //replace the coin the ghost was just on if there was one |
rollschild | 0:5cab8e2cf6a9 | 129 | if(gx1>124) { //This will cause the ghost to wrap around to the left side of the screen if there were no boundary on the far right |
rollschild | 0:5cab8e2cf6a9 | 130 | gx1 = 0; |
rollschild | 0:5cab8e2cf6a9 | 131 | } |
rollschild | 0:5cab8e2cf6a9 | 132 | gx1 = gx1+STEP_SIZE; //Move one step size in the x direction |
rollschild | 0:5cab8e2cf6a9 | 133 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 134 | //redraw the ghost at the new position |
rollschild | 0:5cab8e2cf6a9 | 135 | uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE); |
rollschild | 0:5cab8e2cf6a9 | 136 | uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE); |
rollschild | 0:5cab8e2cf6a9 | 137 | uLCD.filled_circle(gx1+2,gy1-2,1,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 138 | uLCD.filled_circle(gx1-2,gy1-2,1,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 139 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 140 | } |
rollschild | 0:5cab8e2cf6a9 | 141 | |
rollschild | 0:5cab8e2cf6a9 | 142 | //Moves the blue ghost left |
rollschild | 0:5cab8e2cf6a9 | 143 | void bgLEFT(void) |
rollschild | 0:5cab8e2cf6a9 | 144 | { |
rollschild | 0:5cab8e2cf6a9 | 145 | Thread::wait(50); |
rollschild | 0:5cab8e2cf6a9 | 146 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 147 | uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 148 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 149 | replaceCOINS(); |
rollschild | 0:5cab8e2cf6a9 | 150 | if(gx1<4) { |
rollschild | 0:5cab8e2cf6a9 | 151 | gx1 = 124; |
rollschild | 0:5cab8e2cf6a9 | 152 | } |
rollschild | 0:5cab8e2cf6a9 | 153 | gx1 = gx1-STEP_SIZE; |
rollschild | 0:5cab8e2cf6a9 | 154 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 155 | uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE); |
rollschild | 0:5cab8e2cf6a9 | 156 | uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE); |
rollschild | 0:5cab8e2cf6a9 | 157 | uLCD.filled_circle(gx1+2,gy1-2,1,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 158 | uLCD.filled_circle(gx1-2,gy1-2,1,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 159 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 160 | } |
rollschild | 0:5cab8e2cf6a9 | 161 | |
rollschild | 0:5cab8e2cf6a9 | 162 | //Moves the blue ghost up |
rollschild | 0:5cab8e2cf6a9 | 163 | void bgUP(void) |
rollschild | 0:5cab8e2cf6a9 | 164 | { |
rollschild | 0:5cab8e2cf6a9 | 165 | Thread::wait(50); |
rollschild | 0:5cab8e2cf6a9 | 166 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 167 | uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 168 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 169 | replaceCOINS(); |
rollschild | 0:5cab8e2cf6a9 | 170 | if(gy1<4) { |
rollschild | 0:5cab8e2cf6a9 | 171 | gy1 = 124; |
rollschild | 0:5cab8e2cf6a9 | 172 | } |
rollschild | 0:5cab8e2cf6a9 | 173 | gy1 = gy1-STEP_SIZE; |
rollschild | 0:5cab8e2cf6a9 | 174 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 175 | uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE); |
rollschild | 0:5cab8e2cf6a9 | 176 | uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE); |
rollschild | 0:5cab8e2cf6a9 | 177 | uLCD.filled_circle(gx1+2,gy1-2,1,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 178 | uLCD.filled_circle(gx1-2,gy1-2,1,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 179 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 180 | } |
rollschild | 0:5cab8e2cf6a9 | 181 | |
rollschild | 0:5cab8e2cf6a9 | 182 | //Moves the blue ghost down |
rollschild | 0:5cab8e2cf6a9 | 183 | void bgDOWN(void) |
rollschild | 0:5cab8e2cf6a9 | 184 | { |
rollschild | 0:5cab8e2cf6a9 | 185 | Thread::wait(50); |
rollschild | 0:5cab8e2cf6a9 | 186 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 187 | uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 188 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 189 | replaceCOINS(); |
rollschild | 0:5cab8e2cf6a9 | 190 | if(gy1>124) { |
rollschild | 0:5cab8e2cf6a9 | 191 | gy1 = 0; |
rollschild | 0:5cab8e2cf6a9 | 192 | } |
rollschild | 0:5cab8e2cf6a9 | 193 | gy1 = gy1+STEP_SIZE; |
rollschild | 0:5cab8e2cf6a9 | 194 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 195 | uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE); |
rollschild | 0:5cab8e2cf6a9 | 196 | uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE); |
rollschild | 0:5cab8e2cf6a9 | 197 | uLCD.filled_circle(gx1+2,gy1-2,1,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 198 | uLCD.filled_circle(gx1-2,gy1-2,1,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 199 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 200 | } |
rollschild | 0:5cab8e2cf6a9 | 201 | |
rollschild | 0:5cab8e2cf6a9 | 202 | //Force ghost to chase Pacman |
rollschild | 0:5cab8e2cf6a9 | 203 | void follow(void) |
rollschild | 0:5cab8e2cf6a9 | 204 | { |
rollschild | 0:5cab8e2cf6a9 | 205 | if(x==gx1 && y==gy1) { //if the ghost and Pacman are at the same position trigger losing condition |
rollschild | 0:5cab8e2cf6a9 | 206 | win = true; //This is set to true just to exit the check for a win loop and terminate other loops without writing additional conditions |
rollschild | 0:5cab8e2cf6a9 | 207 | lose = true; |
rollschild | 0:5cab8e2cf6a9 | 208 | // return void(); |
rollschild | 0:5cab8e2cf6a9 | 209 | } |
rollschild | 0:5cab8e2cf6a9 | 210 | while(x==gx1 && gy1<y && !win) { //If the ghost is directly above Pacman check to see if moving down is possible, then move down |
rollschild | 0:5cab8e2cf6a9 | 211 | BGclearDOWN(); |
rollschild | 0:5cab8e2cf6a9 | 212 | bgDOWN(); |
rollschild | 0:5cab8e2cf6a9 | 213 | } |
rollschild | 0:5cab8e2cf6a9 | 214 | while(x==gx1 && gy1>y && !win) { |
rollschild | 0:5cab8e2cf6a9 | 215 | BGclearUP(); |
rollschild | 0:5cab8e2cf6a9 | 216 | bgUP(); |
rollschild | 0:5cab8e2cf6a9 | 217 | } |
rollschild | 0:5cab8e2cf6a9 | 218 | while(y==gy1 && gx1<x && !win) { |
rollschild | 0:5cab8e2cf6a9 | 219 | BGclearRIGHT(); |
rollschild | 0:5cab8e2cf6a9 | 220 | bgRIGHT(); |
rollschild | 0:5cab8e2cf6a9 | 221 | } |
rollschild | 0:5cab8e2cf6a9 | 222 | while(y==gy1 && gx1>x && !win) { |
rollschild | 0:5cab8e2cf6a9 | 223 | BGclearLEFT(); |
rollschild | 0:5cab8e2cf6a9 | 224 | bgLEFT(); |
rollschild | 0:5cab8e2cf6a9 | 225 | } |
rollschild | 0:5cab8e2cf6a9 | 226 | } |
rollschild | 0:5cab8e2cf6a9 | 227 | |
rollschild | 0:5cab8e2cf6a9 | 228 | //Ghost selects a direction to move |
rollschild | 0:5cab8e2cf6a9 | 229 | void pickMOVE(void) |
rollschild | 0:5cab8e2cf6a9 | 230 | { |
rollschild | 0:5cab8e2cf6a9 | 231 | while((gx1==x || gy1==y) && abs(x-gx1)+abs(y-gy1)<=16 && !win) { //If Pacman is close by give chase |
rollschild | 0:5cab8e2cf6a9 | 232 | follow(); |
rollschild | 0:5cab8e2cf6a9 | 233 | } |
rollschild | 0:5cab8e2cf6a9 | 234 | int dec = rand()%4; //randomly generate a number from the set 0,1,2,3, which serves as the direction decision |
rollschild | 0:5cab8e2cf6a9 | 235 | if(dec == 0) { |
rollschild | 0:5cab8e2cf6a9 | 236 | BGclearRIGHT(); |
rollschild | 0:5cab8e2cf6a9 | 237 | while(bgcr && !win) { //If decision 0 was reached, check to the the move right until a boundary is reached |
rollschild | 0:5cab8e2cf6a9 | 238 | bgRIGHT(); |
rollschild | 0:5cab8e2cf6a9 | 239 | BGclearRIGHT(); |
rollschild | 0:5cab8e2cf6a9 | 240 | } |
rollschild | 0:5cab8e2cf6a9 | 241 | } else if(dec == 1) { |
rollschild | 0:5cab8e2cf6a9 | 242 | BGclearLEFT(); |
rollschild | 0:5cab8e2cf6a9 | 243 | while(bgcl && !win) { |
rollschild | 0:5cab8e2cf6a9 | 244 | bgLEFT(); |
rollschild | 0:5cab8e2cf6a9 | 245 | BGclearLEFT(); |
rollschild | 0:5cab8e2cf6a9 | 246 | } |
rollschild | 0:5cab8e2cf6a9 | 247 | } else if(dec == 2) { |
rollschild | 0:5cab8e2cf6a9 | 248 | BGclearUP(); |
rollschild | 0:5cab8e2cf6a9 | 249 | while(bgcu && !win) { |
rollschild | 0:5cab8e2cf6a9 | 250 | bgUP(); |
rollschild | 0:5cab8e2cf6a9 | 251 | BGclearUP(); |
rollschild | 0:5cab8e2cf6a9 | 252 | } |
rollschild | 0:5cab8e2cf6a9 | 253 | } else { |
rollschild | 0:5cab8e2cf6a9 | 254 | BGclearDOWN(); |
rollschild | 0:5cab8e2cf6a9 | 255 | while(bgcd && !win) { |
rollschild | 0:5cab8e2cf6a9 | 256 | bgDOWN(); |
rollschild | 0:5cab8e2cf6a9 | 257 | BGclearDOWN(); |
rollschild | 0:5cab8e2cf6a9 | 258 | } |
rollschild | 0:5cab8e2cf6a9 | 259 | } |
rollschild | 0:5cab8e2cf6a9 | 260 | } |
rollschild | 0:5cab8e2cf6a9 | 261 | |
rollschild | 0:5cab8e2cf6a9 | 262 | //Check if Pacman can move one step size to the right (Essentially the same as checking for the ghost) |
rollschild | 0:5cab8e2cf6a9 | 263 | void CHECKclearRIGHT(void) |
rollschild | 0:5cab8e2cf6a9 | 264 | { |
rollschild | 0:5cab8e2cf6a9 | 265 | clearRIGHT = true; |
rollschild | 0:5cab8e2cf6a9 | 266 | for(i=x; i <= x+CLEARANCE; i++) { |
rollschild | 0:5cab8e2cf6a9 | 267 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 268 | if(uLCD.read_pixel(i,y)==uLCD.read_pixel(4,4)) { |
rollschild | 0:5cab8e2cf6a9 | 269 | clearRIGHT = false; |
rollschild | 0:5cab8e2cf6a9 | 270 | } |
rollschild | 0:5cab8e2cf6a9 | 271 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 272 | } |
rollschild | 0:5cab8e2cf6a9 | 273 | } |
rollschild | 0:5cab8e2cf6a9 | 274 | |
rollschild | 0:5cab8e2cf6a9 | 275 | //Check if Pacman can move left |
rollschild | 0:5cab8e2cf6a9 | 276 | void CHECKclearLEFT(void) |
rollschild | 0:5cab8e2cf6a9 | 277 | { |
rollschild | 0:5cab8e2cf6a9 | 278 | clearLEFT = true; |
rollschild | 0:5cab8e2cf6a9 | 279 | for(i=x; i >= x-CLEARANCE; i--) { |
rollschild | 0:5cab8e2cf6a9 | 280 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 281 | if(uLCD.read_pixel(i,y)==uLCD.read_pixel(4,4)) { |
rollschild | 0:5cab8e2cf6a9 | 282 | clearLEFT = false; |
rollschild | 0:5cab8e2cf6a9 | 283 | } |
rollschild | 0:5cab8e2cf6a9 | 284 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 285 | } |
rollschild | 0:5cab8e2cf6a9 | 286 | } |
rollschild | 0:5cab8e2cf6a9 | 287 | |
rollschild | 0:5cab8e2cf6a9 | 288 | //Check if Pacman can move up |
rollschild | 0:5cab8e2cf6a9 | 289 | void CHECKclearUP(void) |
rollschild | 0:5cab8e2cf6a9 | 290 | { |
rollschild | 0:5cab8e2cf6a9 | 291 | clearUP = true; |
rollschild | 0:5cab8e2cf6a9 | 292 | for(i=y; i >= y-CLEARANCE; i--) { |
rollschild | 0:5cab8e2cf6a9 | 293 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 294 | if(uLCD.read_pixel(x,i)==uLCD.read_pixel(4,4)) { |
rollschild | 0:5cab8e2cf6a9 | 295 | clearUP = false; |
rollschild | 0:5cab8e2cf6a9 | 296 | } |
rollschild | 0:5cab8e2cf6a9 | 297 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 298 | } |
rollschild | 0:5cab8e2cf6a9 | 299 | } |
rollschild | 0:5cab8e2cf6a9 | 300 | |
rollschild | 0:5cab8e2cf6a9 | 301 | //Check if Pacman can move down |
rollschild | 0:5cab8e2cf6a9 | 302 | void CHECKclearDOWN(void) |
rollschild | 0:5cab8e2cf6a9 | 303 | { |
rollschild | 0:5cab8e2cf6a9 | 304 | clearDOWN = true; |
rollschild | 0:5cab8e2cf6a9 | 305 | for(i=y; i <= y+CLEARANCE; i++) { |
rollschild | 0:5cab8e2cf6a9 | 306 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 307 | if(uLCD.read_pixel(x,i)==uLCD.read_pixel(4,4)) { |
rollschild | 0:5cab8e2cf6a9 | 308 | clearDOWN = false; |
rollschild | 0:5cab8e2cf6a9 | 309 | } |
rollschild | 0:5cab8e2cf6a9 | 310 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 311 | } |
rollschild | 0:5cab8e2cf6a9 | 312 | } |
rollschild | 0:5cab8e2cf6a9 | 313 | |
rollschild | 0:5cab8e2cf6a9 | 314 | //This function tracks the coin Pacman eats as he passes over it |
rollschild | 0:5cab8e2cf6a9 | 315 | void changeCOINS(void) |
rollschild | 0:5cab8e2cf6a9 | 316 | { |
rollschild | 0:5cab8e2cf6a9 | 317 | for(int m=0; m<81; m++) { |
rollschild | 0:5cab8e2cf6a9 | 318 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 319 | if(x == coins[m][0] && y == coins[m][1]) { //Compare Pacman's position to the set of coins |
rollschild | 0:5cab8e2cf6a9 | 320 | coins[m][0]=64; //If there is a match, change that coins location to the center of the board where Pacman |
rollschild | 0:5cab8e2cf6a9 | 321 | coins[m][1]=64; //cannot go, but do not draw the coin |
rollschild | 0:5cab8e2cf6a9 | 322 | } |
rollschild | 0:5cab8e2cf6a9 | 323 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 324 | } |
rollschild | 0:5cab8e2cf6a9 | 325 | } |
rollschild | 0:5cab8e2cf6a9 | 326 | |
rollschild | 0:5cab8e2cf6a9 | 327 | //Move Pacman one step size to the right |
rollschild | 0:5cab8e2cf6a9 | 328 | void PACmoveRIGHT(void) |
rollschild | 0:5cab8e2cf6a9 | 329 | { |
rollschild | 0:5cab8e2cf6a9 | 330 | while(clearRIGHT && !win) { //Not win indicates the game has not ended |
rollschild | 0:5cab8e2cf6a9 | 331 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 332 | uLCD.filled_circle(x,y,PAC_SIZE,BLACK); //Erase Pacman at his last location |
rollschild | 0:5cab8e2cf6a9 | 333 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 334 | if(x>124) { //wrap around if moving off the board |
rollschild | 0:5cab8e2cf6a9 | 335 | x = 0; |
rollschild | 0:5cab8e2cf6a9 | 336 | } |
rollschild | 0:5cab8e2cf6a9 | 337 | x = x + STEP_SIZE; //move Pacman one step size to the right |
rollschild | 0:5cab8e2cf6a9 | 338 | changeCOINS(); //Track the coin that was eaten at the last location |
rollschild | 0:5cab8e2cf6a9 | 339 | |
rollschild | 0:5cab8e2cf6a9 | 340 | if(x%(2*STEP_SIZE) == 0) { //There are two drawings provided for Pacman. The if statement causes Pacman to open his mouth every other move. |
rollschild | 0:5cab8e2cf6a9 | 341 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 342 | uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00); |
rollschild | 0:5cab8e2cf6a9 | 343 | uLCD.filled_rectangle(x+2,y-2,x+PAC_SIZE,y+2,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 344 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 345 | } else { |
rollschild | 0:5cab8e2cf6a9 | 346 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 347 | uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00); |
rollschild | 0:5cab8e2cf6a9 | 348 | uLCD.filled_rectangle(x+2,y,x+PAC_SIZE,y+1,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 349 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 350 | } |
rollschild | 0:5cab8e2cf6a9 | 351 | /*if(jsx <= .9) //If the user is still holding the joystick to the right, remain in this loop |
rollschild | 0:5cab8e2cf6a9 | 352 | { |
rollschild | 0:5cab8e2cf6a9 | 353 | checkMOVE(); |
rollschild | 0:5cab8e2cf6a9 | 354 | }*/ |
rollschild | 0:5cab8e2cf6a9 | 355 | CHECKclearRIGHT(); //If the user remains in the loop, check for a boundary to the right |
rollschild | 0:5cab8e2cf6a9 | 356 | Thread::wait(10); |
rollschild | 0:5cab8e2cf6a9 | 357 | } |
rollschild | 0:5cab8e2cf6a9 | 358 | } |
rollschild | 0:5cab8e2cf6a9 | 359 | |
rollschild | 0:5cab8e2cf6a9 | 360 | //Move Pacman left |
rollschild | 0:5cab8e2cf6a9 | 361 | void PACmoveLEFT(void) |
rollschild | 0:5cab8e2cf6a9 | 362 | { |
rollschild | 0:5cab8e2cf6a9 | 363 | while(clearLEFT && !win) { |
rollschild | 0:5cab8e2cf6a9 | 364 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 365 | uLCD.filled_circle(x,y,PAC_SIZE,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 366 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 367 | if(x<4) { |
rollschild | 0:5cab8e2cf6a9 | 368 | x = 128; |
rollschild | 0:5cab8e2cf6a9 | 369 | } |
rollschild | 0:5cab8e2cf6a9 | 370 | x = x-STEP_SIZE; |
rollschild | 0:5cab8e2cf6a9 | 371 | changeCOINS(); |
rollschild | 0:5cab8e2cf6a9 | 372 | if(x%(2*STEP_SIZE) == 0) { |
rollschild | 0:5cab8e2cf6a9 | 373 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 374 | uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00); |
rollschild | 0:5cab8e2cf6a9 | 375 | uLCD.filled_rectangle(x-2,y-2,x-PAC_SIZE,y+2,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 376 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 377 | } else { |
rollschild | 0:5cab8e2cf6a9 | 378 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 379 | uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00); |
rollschild | 0:5cab8e2cf6a9 | 380 | uLCD.filled_rectangle(x-2,y,x-PAC_SIZE,y+1,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 381 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 382 | } |
rollschild | 0:5cab8e2cf6a9 | 383 | /*if(jsx >= .1) |
rollschild | 0:5cab8e2cf6a9 | 384 | { |
rollschild | 0:5cab8e2cf6a9 | 385 | checkMOVE(); |
rollschild | 0:5cab8e2cf6a9 | 386 | }*/ |
rollschild | 0:5cab8e2cf6a9 | 387 | CHECKclearLEFT(); |
rollschild | 0:5cab8e2cf6a9 | 388 | Thread::wait(10); |
rollschild | 0:5cab8e2cf6a9 | 389 | } |
rollschild | 0:5cab8e2cf6a9 | 390 | } |
rollschild | 0:5cab8e2cf6a9 | 391 | |
rollschild | 0:5cab8e2cf6a9 | 392 | //Move Pacman up |
rollschild | 0:5cab8e2cf6a9 | 393 | void PACmoveUP(void) |
rollschild | 0:5cab8e2cf6a9 | 394 | { |
rollschild | 0:5cab8e2cf6a9 | 395 | while(clearUP && !win) { |
rollschild | 0:5cab8e2cf6a9 | 396 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 397 | uLCD.filled_circle(x,y,PAC_SIZE,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 398 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 399 | if(y<4) { |
rollschild | 0:5cab8e2cf6a9 | 400 | y = 128; |
rollschild | 0:5cab8e2cf6a9 | 401 | } |
rollschild | 0:5cab8e2cf6a9 | 402 | y = y-STEP_SIZE; |
rollschild | 0:5cab8e2cf6a9 | 403 | changeCOINS(); |
rollschild | 0:5cab8e2cf6a9 | 404 | if(y%(2*STEP_SIZE) == 0) { |
rollschild | 0:5cab8e2cf6a9 | 405 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 406 | uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00); |
rollschild | 0:5cab8e2cf6a9 | 407 | uLCD.filled_rectangle(x-2,y-2,x+2,y-PAC_SIZE,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 408 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 409 | } else { |
rollschild | 0:5cab8e2cf6a9 | 410 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 411 | uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00); |
rollschild | 0:5cab8e2cf6a9 | 412 | uLCD.filled_rectangle(x,y-2,x+1,y-PAC_SIZE,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 413 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 414 | } |
rollschild | 0:5cab8e2cf6a9 | 415 | CHECKclearUP(); |
rollschild | 0:5cab8e2cf6a9 | 416 | Thread::wait(10); |
rollschild | 0:5cab8e2cf6a9 | 417 | } |
rollschild | 0:5cab8e2cf6a9 | 418 | } |
rollschild | 0:5cab8e2cf6a9 | 419 | |
rollschild | 0:5cab8e2cf6a9 | 420 | //Move Pacman down |
rollschild | 0:5cab8e2cf6a9 | 421 | void PACmoveDOWN(void) |
rollschild | 0:5cab8e2cf6a9 | 422 | { |
rollschild | 0:5cab8e2cf6a9 | 423 | while(clearDOWN && !win) { |
rollschild | 0:5cab8e2cf6a9 | 424 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 425 | uLCD.filled_circle(x,y,PAC_SIZE,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 426 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 427 | if(y>124) { |
rollschild | 0:5cab8e2cf6a9 | 428 | y = 0; |
rollschild | 0:5cab8e2cf6a9 | 429 | } |
rollschild | 0:5cab8e2cf6a9 | 430 | y = y+STEP_SIZE; |
rollschild | 0:5cab8e2cf6a9 | 431 | changeCOINS(); |
rollschild | 0:5cab8e2cf6a9 | 432 | if(y%(2*STEP_SIZE) == 0) { |
rollschild | 0:5cab8e2cf6a9 | 433 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 434 | uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00); |
rollschild | 0:5cab8e2cf6a9 | 435 | uLCD.filled_rectangle(x-2,y+2,x+2,y+PAC_SIZE,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 436 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 437 | } else { |
rollschild | 0:5cab8e2cf6a9 | 438 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 439 | uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00); |
rollschild | 0:5cab8e2cf6a9 | 440 | uLCD.filled_rectangle(x,y+2,x+1,y+PAC_SIZE,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 441 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 442 | } |
rollschild | 0:5cab8e2cf6a9 | 443 | /*if(jsy >= .1) |
rollschild | 0:5cab8e2cf6a9 | 444 | { |
rollschild | 0:5cab8e2cf6a9 | 445 | checkMOVE(); |
rollschild | 0:5cab8e2cf6a9 | 446 | }*/ |
rollschild | 0:5cab8e2cf6a9 | 447 | CHECKclearDOWN(); |
rollschild | 0:5cab8e2cf6a9 | 448 | Thread::wait(10); |
rollschild | 0:5cab8e2cf6a9 | 449 | } |
rollschild | 0:5cab8e2cf6a9 | 450 | } |
rollschild | 0:5cab8e2cf6a9 | 451 | |
rollschild | 0:5cab8e2cf6a9 | 452 | //Read the input from the joystick and select a direction to move |
rollschild | 0:5cab8e2cf6a9 | 453 | //The thresholds are set near the end of their ranges to eliminate unintentional moves as much as possible |
rollschild | 0:5cab8e2cf6a9 | 454 | void checkMOVE(void) |
rollschild | 0:5cab8e2cf6a9 | 455 | { |
rollschild | 0:5cab8e2cf6a9 | 456 | if(right_pb) { |
rollschild | 0:5cab8e2cf6a9 | 457 | CHECKclearRIGHT(); |
rollschild | 0:5cab8e2cf6a9 | 458 | PACmoveRIGHT(); |
rollschild | 0:5cab8e2cf6a9 | 459 | } else if(left_pb) { |
rollschild | 0:5cab8e2cf6a9 | 460 | CHECKclearLEFT(); |
rollschild | 0:5cab8e2cf6a9 | 461 | PACmoveLEFT(); |
rollschild | 0:5cab8e2cf6a9 | 462 | } else if(up_pb){ |
rollschild | 0:5cab8e2cf6a9 | 463 | CHECKclearUP(); |
rollschild | 0:5cab8e2cf6a9 | 464 | PACmoveUP(); |
rollschild | 0:5cab8e2cf6a9 | 465 | } else if(down_pb){ |
rollschild | 0:5cab8e2cf6a9 | 466 | CHECKclearDOWN(); |
rollschild | 0:5cab8e2cf6a9 | 467 | PACmoveDOWN(); |
rollschild | 0:5cab8e2cf6a9 | 468 | } |
rollschild | 0:5cab8e2cf6a9 | 469 | else {} |
rollschild | 0:5cab8e2cf6a9 | 470 | } |
rollschild | 0:5cab8e2cf6a9 | 471 | |
rollschild | 0:5cab8e2cf6a9 | 472 | //Draw the boudaries for the game using the uLCD graphics commands |
rollschild | 0:5cab8e2cf6a9 | 473 | void drawBORDERS(void) |
rollschild | 0:5cab8e2cf6a9 | 474 | { |
rollschild | 0:5cab8e2cf6a9 | 475 | //Outer Border |
rollschild | 0:5cab8e2cf6a9 | 476 | uLCD.rectangle(4,4,124,124,RED); |
rollschild | 0:5cab8e2cf6a9 | 477 | uLCD.line(8,8,8,120,RED); |
rollschild | 0:5cab8e2cf6a9 | 478 | uLCD.line(8,8,62,8,RED); |
rollschild | 0:5cab8e2cf6a9 | 479 | uLCD.line(62,8,62,32,RED); |
rollschild | 0:5cab8e2cf6a9 | 480 | uLCD.line(62,32,66,32,RED); |
rollschild | 0:5cab8e2cf6a9 | 481 | uLCD.line(66,32,66,8,RED); |
rollschild | 0:5cab8e2cf6a9 | 482 | uLCD.line(66,8,120,8,RED); |
rollschild | 0:5cab8e2cf6a9 | 483 | uLCD.line(120,8,120,120,RED); |
rollschild | 0:5cab8e2cf6a9 | 484 | uLCD.line(120,120,66,120,RED); |
rollschild | 0:5cab8e2cf6a9 | 485 | uLCD.line(66,120,66,96,RED); |
rollschild | 0:5cab8e2cf6a9 | 486 | uLCD.line(66,96,62,96,RED); |
rollschild | 0:5cab8e2cf6a9 | 487 | uLCD.line(62,96,62,120,RED); |
rollschild | 0:5cab8e2cf6a9 | 488 | uLCD.line(62,120,8,120,RED); |
rollschild | 0:5cab8e2cf6a9 | 489 | //Inner Rectangle |
rollschild | 0:5cab8e2cf6a9 | 490 | uLCD.rectangle(52,52,76,76,RED); |
rollschild | 0:5cab8e2cf6a9 | 491 | uLCD.rectangle(48,48,80,80,RED); |
rollschild | 0:5cab8e2cf6a9 | 492 | //Upper Left Corner |
rollschild | 0:5cab8e2cf6a9 | 493 | uLCD.line(48,24,24,24,RED); |
rollschild | 0:5cab8e2cf6a9 | 494 | uLCD.line(24,24,24,56,RED); |
rollschild | 0:5cab8e2cf6a9 | 495 | uLCD.line(24,56,32,56,RED); |
rollschild | 0:5cab8e2cf6a9 | 496 | uLCD.line(32,56,32,32,RED); |
rollschild | 0:5cab8e2cf6a9 | 497 | uLCD.line(32,32,48,32,RED); |
rollschild | 0:5cab8e2cf6a9 | 498 | uLCD.line(48,32,48,24,RED); |
rollschild | 0:5cab8e2cf6a9 | 499 | //Upper Right Corner |
rollschild | 0:5cab8e2cf6a9 | 500 | uLCD.line(80,24,104,24,RED); |
rollschild | 0:5cab8e2cf6a9 | 501 | uLCD.line(104,24,104,56,RED); |
rollschild | 0:5cab8e2cf6a9 | 502 | uLCD.line(104,56,96,56,RED); |
rollschild | 0:5cab8e2cf6a9 | 503 | uLCD.line(96,56,96,32,RED); |
rollschild | 0:5cab8e2cf6a9 | 504 | uLCD.line(96,32,80,32,RED); |
rollschild | 0:5cab8e2cf6a9 | 505 | uLCD.line(80,32,80,24,RED); |
rollschild | 0:5cab8e2cf6a9 | 506 | //Lower Left Corner |
rollschild | 0:5cab8e2cf6a9 | 507 | uLCD.line(48,104,24,104,RED); |
rollschild | 0:5cab8e2cf6a9 | 508 | uLCD.line(24,104,24,72,RED); |
rollschild | 0:5cab8e2cf6a9 | 509 | uLCD.line(24,72,32,72,RED); |
rollschild | 0:5cab8e2cf6a9 | 510 | uLCD.line(32,72,32,96,RED); |
rollschild | 0:5cab8e2cf6a9 | 511 | uLCD.line(32,96,48,96,RED); |
rollschild | 0:5cab8e2cf6a9 | 512 | uLCD.line(48,96,48,104,RED); |
rollschild | 0:5cab8e2cf6a9 | 513 | //Lower Right Corner |
rollschild | 0:5cab8e2cf6a9 | 514 | uLCD.line(80,104,104,104,RED); |
rollschild | 0:5cab8e2cf6a9 | 515 | uLCD.line(104,104,104,72,RED); |
rollschild | 0:5cab8e2cf6a9 | 516 | uLCD.line(104,72,96,72,RED); |
rollschild | 0:5cab8e2cf6a9 | 517 | uLCD.line(96,72,96,96,RED); |
rollschild | 0:5cab8e2cf6a9 | 518 | uLCD.line(96,96,80,96,RED); |
rollschild | 0:5cab8e2cf6a9 | 519 | uLCD.line(80,96,80,104,RED); |
rollschild | 0:5cab8e2cf6a9 | 520 | } |
rollschild | 0:5cab8e2cf6a9 | 521 | |
rollschild | 0:5cab8e2cf6a9 | 522 | void placeCOINS(void) |
rollschild | 0:5cab8e2cf6a9 | 523 | { |
rollschild | 0:5cab8e2cf6a9 | 524 | for(int j=0; j<81; j++) { |
rollschild | 0:5cab8e2cf6a9 | 525 | uLCD.filled_circle(coins[j][0],coins[j][1],1,0xFFFF00); //Draw the coins in their initial locations |
rollschild | 0:5cab8e2cf6a9 | 526 | } |
rollschild | 0:5cab8e2cf6a9 | 527 | } |
rollschild | 0:5cab8e2cf6a9 | 528 | |
rollschild | 0:5cab8e2cf6a9 | 529 | //Draw all the initial states of the game |
rollschild | 0:5cab8e2cf6a9 | 530 | void initialize(void) |
rollschild | 0:5cab8e2cf6a9 | 531 | { |
rollschild | 0:5cab8e2cf6a9 | 532 | drawBORDERS(); |
rollschild | 0:5cab8e2cf6a9 | 533 | placeCOINS(); |
rollschild | 0:5cab8e2cf6a9 | 534 | uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00); |
rollschild | 0:5cab8e2cf6a9 | 535 | uLCD.filled_rectangle(x-2,y-2,x-PAC_SIZE,y+2,BLACK); |
rollschild | 0:5cab8e2cf6a9 | 536 | } |
rollschild | 0:5cab8e2cf6a9 | 537 | |
rollschild | 0:5cab8e2cf6a9 | 538 | //Check to see if all the coins have been eaten |
rollschild | 0:5cab8e2cf6a9 | 539 | void checkWIN(void) |
rollschild | 0:5cab8e2cf6a9 | 540 | { |
rollschild | 0:5cab8e2cf6a9 | 541 | win = true; |
rollschild | 0:5cab8e2cf6a9 | 542 | for(int k=0; k<81; k++) { |
rollschild | 0:5cab8e2cf6a9 | 543 | lcd_mutex.lock(); |
rollschild | 0:5cab8e2cf6a9 | 544 | if(coins[k][0]!=64 || coins[k][1]!=64) { //Check the locations of all coins and if 1 has coordinates other than (64,64) the user has not won |
rollschild | 0:5cab8e2cf6a9 | 545 | win = false; |
rollschild | 0:5cab8e2cf6a9 | 546 | } |
rollschild | 0:5cab8e2cf6a9 | 547 | lcd_mutex.unlock(); |
rollschild | 0:5cab8e2cf6a9 | 548 | } |
rollschild | 0:5cab8e2cf6a9 | 549 | } |
rollschild | 0:5cab8e2cf6a9 | 550 | |
rollschild | 0:5cab8e2cf6a9 | 551 | //Thread supervising the joystick inputs and moving Pacman accordingly |
rollschild | 0:5cab8e2cf6a9 | 552 | void pacMOVE(void const *args) |
rollschild | 0:5cab8e2cf6a9 | 553 | { |
rollschild | 0:5cab8e2cf6a9 | 554 | while(!win) { |
rollschild | 0:5cab8e2cf6a9 | 555 | checkMOVE(); |
rollschild | 0:5cab8e2cf6a9 | 556 | Thread::wait(10); |
rollschild | 0:5cab8e2cf6a9 | 557 | } |
rollschild | 0:5cab8e2cf6a9 | 558 | } |
rollschild | 0:5cab8e2cf6a9 | 559 | |
rollschild | 0:5cab8e2cf6a9 | 560 | //Thread controlling the movement of the blue ghost |
rollschild | 0:5cab8e2cf6a9 | 561 | void blueGHOST(void const *args) |
rollschild | 0:5cab8e2cf6a9 | 562 | { |
rollschild | 0:5cab8e2cf6a9 | 563 | while(!win) { |
rollschild | 0:5cab8e2cf6a9 | 564 | pickMOVE(); |
rollschild | 0:5cab8e2cf6a9 | 565 | } |
rollschild | 0:5cab8e2cf6a9 | 566 | } |
rollschild | 0:5cab8e2cf6a9 | 567 | |
rollschild | 0:5cab8e2cf6a9 | 568 | int main() |
rollschild | 0:5cab8e2cf6a9 | 569 | { |
rollschild | 0:5cab8e2cf6a9 | 570 | uLCD.cls(); |
rollschild | 0:5cab8e2cf6a9 | 571 | uLCD.baudrate(9600); |
rollschild | 0:5cab8e2cf6a9 | 572 | left_pb.mode(PullUp); // The variable left_pb will be zero when the pushbutton for moving the player left is pressed |
rollschild | 0:5cab8e2cf6a9 | 573 | right_pb.mode(PullUp); // The variable rightt_pb will be zero when the pushbutton for moving the player right is pressed |
rollschild | 0:5cab8e2cf6a9 | 574 | up_pb.mode(PullUp); //the variable fire_pb will be zero when the pushbutton for firing a missile is pressed |
rollschild | 0:5cab8e2cf6a9 | 575 | down_pb.mode(PullUp); //the variable fire_pb will be zero when the pushbutton for firing a missile is pressed |
rollschild | 0:5cab8e2cf6a9 | 576 | initialize(); //Draw the level setup |
rollschild | 0:5cab8e2cf6a9 | 577 | Thread pm(pacMOVE); //Start the thread for moving Pacman |
rollschild | 0:5cab8e2cf6a9 | 578 | Thread bg(blueGHOST); //Start the thread for moving the blue ghost |
rollschild | 0:5cab8e2cf6a9 | 579 | |
rollschild | 0:5cab8e2cf6a9 | 580 | Thread::wait(5000); //Wait some time before checking the win conditions since it will take around 30 secs to eat all 81 coins |
rollschild | 0:5cab8e2cf6a9 | 581 | while(!win) { //Check to see if there was a win once every tenth of a second |
rollschild | 0:5cab8e2cf6a9 | 582 | checkWIN(); |
rollschild | 0:5cab8e2cf6a9 | 583 | Thread::wait(10); |
rollschild | 0:5cab8e2cf6a9 | 584 | } |
rollschild | 0:5cab8e2cf6a9 | 585 | |
rollschild | 0:5cab8e2cf6a9 | 586 | Thread::wait(1000); //Wait one second before displaying end message |
rollschild | 0:5cab8e2cf6a9 | 587 | |
rollschild | 0:5cab8e2cf6a9 | 588 | if(lose) { //Print game over message if lose (determined in the follow function) |
rollschild | 0:5cab8e2cf6a9 | 589 | uLCD.cls(); |
rollschild | 0:5cab8e2cf6a9 | 590 | uLCD.printf("Sorry\nGame Over"); |
rollschild | 0:5cab8e2cf6a9 | 591 | } else if(win){ |
rollschild | 0:5cab8e2cf6a9 | 592 | uLCD.cls(); |
rollschild | 0:5cab8e2cf6a9 | 593 | uLCD.printf("Congratulations!\nYou Won!"); |
rollschild | 0:5cab8e2cf6a9 | 594 | } |
rollschild | 0:5cab8e2cf6a9 | 595 | |
rollschild | 0:5cab8e2cf6a9 | 596 | while(1) { |
rollschild | 0:5cab8e2cf6a9 | 597 | /*if(lose) { //Print game over message if lose (determined in the follow function) |
rollschild | 0:5cab8e2cf6a9 | 598 | uLCD.cls(); |
rollschild | 0:5cab8e2cf6a9 | 599 | uLCD.printf("Sorry\nGame Over"); |
rollschild | 0:5cab8e2cf6a9 | 600 | } else if(win){ |
rollschild | 0:5cab8e2cf6a9 | 601 | uLCD.cls(); |
rollschild | 0:5cab8e2cf6a9 | 602 | uLCD.printf("Congratulations!\nYou Won!"); |
rollschild | 0:5cab8e2cf6a9 | 603 | }*/ |
rollschild | 0:5cab8e2cf6a9 | 604 | Thread::wait(1000); |
rollschild | 0:5cab8e2cf6a9 | 605 | } |
rollschild | 0:5cab8e2cf6a9 | 606 | } |