A zombie game made for the uLCD

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

Fork of uLCD144G2_demo by jim hamblen

Committer:
rjones75
Date:
Sun Mar 13 16:00:46 2016 +0000
Revision:
10:9d16de327719
Parent:
8:31e63caf37e2
Child:
11:4b75ea66467d
done

Who changed what in which revision?

UserRevisionLine numberNew contents of line
4180_1 0:cfcf73272647 1 #include "mbed.h"
4180_1 2:75727e89a717 2 #include "uLCD_4DGL.h"
rjones75 10:9d16de327719 3 #include "Speaker.h"
rjones75 10:9d16de327719 4 #include "rtos.h"
4180_1 0:cfcf73272647 5
rjones75 10:9d16de327719 6 //First make the Nav_Switch class for using the joystick
rjones75 10:9d16de327719 7 class Nav_Switch
4180_1 2:75727e89a717 8 {
rjones75 10:9d16de327719 9 public:
rjones75 10:9d16de327719 10 Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire);
rjones75 10:9d16de327719 11 int read();
rjones75 10:9d16de327719 12 //boolean functions to test each switch
rjones75 10:9d16de327719 13 bool up();
rjones75 10:9d16de327719 14 bool down();
rjones75 10:9d16de327719 15 bool left();
rjones75 10:9d16de327719 16 bool right();
rjones75 10:9d16de327719 17 bool fire();
rjones75 10:9d16de327719 18 //automatic read on RHS
rjones75 10:9d16de327719 19 operator int ();
rjones75 10:9d16de327719 20 //index to any switch array style
rjones75 10:9d16de327719 21 bool operator[](int index) {
rjones75 10:9d16de327719 22 return _pins[index];
rjones75 10:9d16de327719 23 };
rjones75 10:9d16de327719 24 private:
rjones75 10:9d16de327719 25 BusIn _pins;
4180_1 7:7bd7397ab89f 26
rjones75 10:9d16de327719 27 };
rjones75 10:9d16de327719 28 Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire):
rjones75 10:9d16de327719 29 _pins(up, down, left, right, fire)
rjones75 10:9d16de327719 30 {
rjones75 10:9d16de327719 31 _pins.mode(PullUp); //needed if pullups not on board or a bare nav switch is used - delete otherwise
rjones75 10:9d16de327719 32 wait(0.001); //delays just a bit for pullups to pull inputs high
rjones75 10:9d16de327719 33 }
rjones75 10:9d16de327719 34 inline bool Nav_Switch::up()
rjones75 10:9d16de327719 35 {
rjones75 10:9d16de327719 36 return !(_pins[0]);
rjones75 10:9d16de327719 37 }
rjones75 10:9d16de327719 38 inline bool Nav_Switch::down()
rjones75 10:9d16de327719 39 {
rjones75 10:9d16de327719 40 return !(_pins[1]);
rjones75 10:9d16de327719 41 }
rjones75 10:9d16de327719 42 inline bool Nav_Switch::left()
rjones75 10:9d16de327719 43 {
rjones75 10:9d16de327719 44 return !(_pins[2]);
rjones75 10:9d16de327719 45 }
rjones75 10:9d16de327719 46 inline bool Nav_Switch::right()
rjones75 10:9d16de327719 47 {
rjones75 10:9d16de327719 48 return !(_pins[3]);
rjones75 10:9d16de327719 49 }
rjones75 10:9d16de327719 50 inline bool Nav_Switch::fire()
rjones75 10:9d16de327719 51 {
rjones75 10:9d16de327719 52 return !(_pins[4]);
rjones75 10:9d16de327719 53 }
rjones75 10:9d16de327719 54 inline int Nav_Switch::read()
rjones75 10:9d16de327719 55 {
rjones75 10:9d16de327719 56 return _pins.read();
rjones75 10:9d16de327719 57 }
rjones75 10:9d16de327719 58 inline Nav_Switch::operator int ()
rjones75 10:9d16de327719 59 {
rjones75 10:9d16de327719 60 return _pins.read();
rjones75 10:9d16de327719 61 }
rjones75 10:9d16de327719 62
rjones75 10:9d16de327719 63 //Now initialize
rjones75 10:9d16de327719 64 uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin;
rjones75 10:9d16de327719 65 Nav_Switch myNav(p11,p14,p13,p15,p12);
rjones75 10:9d16de327719 66 Speaker mySpeaker(p21);
rjones75 10:9d16de327719 67
rjones75 10:9d16de327719 68 //Game states: Start screen, playing, and game over
rjones75 10:9d16de327719 69 enum gamestate {
rjones75 10:9d16de327719 70 start,
rjones75 10:9d16de327719 71 playing,
rjones75 10:9d16de327719 72 gameover
rjones75 10:9d16de327719 73 };
rjones75 10:9d16de327719 74
rjones75 10:9d16de327719 75 //Which way you're facing is where you fire your gun
rjones75 10:9d16de327719 76 enum facingDirection {
rjones75 10:9d16de327719 77 up,
rjones75 10:9d16de327719 78 down,
rjones75 10:9d16de327719 79 left,
rjones75 10:9d16de327719 80 right
rjones75 10:9d16de327719 81 };
rjones75 10:9d16de327719 82
rjones75 10:9d16de327719 83 //Global variables used by SpeakerThread
rjones75 10:9d16de327719 84 //The game state
rjones75 10:9d16de327719 85 int state=start;
rjones75 10:9d16de327719 86 //Checks for each bullet (up,down,left,right) to see if it hit an enemy
rjones75 10:9d16de327719 87 bool hitU=false, hitD=false, hitL=false, hitR=false;
rjones75 10:9d16de327719 88
rjones75 10:9d16de327719 89 void SpeakerThread(void const *args)
rjones75 10:9d16de327719 90 {
rjones75 10:9d16de327719 91 while(1) {
rjones75 10:9d16de327719 92 if(myNav.fire() && state==playing) {
rjones75 10:9d16de327719 93 //Play noise when gun is fired
rjones75 10:9d16de327719 94 mySpeaker.PlayNote(500.0,0.1,0.5);
4180_1 3:454d1f4c8fd7 95 }
rjones75 10:9d16de327719 96 if(hitU || hitD || hitL || hitR) {
rjones75 10:9d16de327719 97 //Play two notes when enemy hit.
rjones75 10:9d16de327719 98 mySpeaker.PlayNote(300.0,0.05,0.5);
rjones75 10:9d16de327719 99 mySpeaker.PlayNote(250.0,0.05,0.5);
4180_1 5:a1ef40ff0f78 100 }
4180_1 5:a1ef40ff0f78 101 }
4180_1 6:f752accd632c 102 }
4180_1 7:7bd7397ab89f 103
4180_1 7:7bd7397ab89f 104
4180_1 8:31e63caf37e2 105
rjones75 10:9d16de327719 106 int main()
rjones75 10:9d16de327719 107 {
rjones75 10:9d16de327719 108 while(1) {
rjones75 10:9d16de327719 109 //Score
rjones75 10:9d16de327719 110 int score=0;
rjones75 10:9d16de327719 111 //Player position (initialized at center).
rjones75 10:9d16de327719 112 int Px1=63-1,Px2=63+1,Py1=63-1,Py2=63+1;
rjones75 10:9d16de327719 113 //X and Y coordinates for each bullet
rjones75 10:9d16de327719 114 int BUx=0, BUy=0, BLx=0, BLy=0;
rjones75 10:9d16de327719 115 int BDx=127, BDy=127, BRx=127, BRy=127;
rjones75 10:9d16de327719 116 //Zombie coordinates. Z[0][0] = x coordinate of zombie 1, Z[0][1] = y coordinate of zombie 1.
rjones75 10:9d16de327719 117 //Z[0][0] = x1 coordinate, Z[0][0]+2 = x2 coordinate. Same method for y1 and y2.
rjones75 10:9d16de327719 118 int Z[1][2];
rjones75 10:9d16de327719 119 for(int i=0; i<2; i++) {
rjones75 10:9d16de327719 120 for(int j=0; j<2; j++) {
rjones75 10:9d16de327719 121 Z[i][j]=0;
rjones75 10:9d16de327719 122 }
rjones75 10:9d16de327719 123 }
rjones75 10:9d16de327719 124 //Which way the player is facing
rjones75 10:9d16de327719 125 int facing=down;
rjones75 10:9d16de327719 126 //Threads
rjones75 10:9d16de327719 127 Thread speaker(SpeakerThread);
rjones75 10:9d16de327719 128 //Display the start screen
rjones75 10:9d16de327719 129 uLCD.media_init();
rjones75 10:9d16de327719 130 uLCD.set_sector_address(0x001D, 0x4C01);
rjones75 10:9d16de327719 131 uLCD.display_image(0,0);
rjones75 10:9d16de327719 132 //Switch to the playing state when FIRE is pressed
rjones75 10:9d16de327719 133 while(state==start) {
rjones75 10:9d16de327719 134 if(myNav.fire()) {
rjones75 10:9d16de327719 135 uLCD.cls();
rjones75 10:9d16de327719 136 wait(1.0);
rjones75 10:9d16de327719 137 state=playing;
rjones75 10:9d16de327719 138 }
rjones75 10:9d16de327719 139 }
rjones75 10:9d16de327719 140
rjones75 10:9d16de327719 141 //Draw player and zombie
rjones75 10:9d16de327719 142 uLCD.filled_rectangle(Px1,Py1,Px2,Py2,BLUE);
rjones75 10:9d16de327719 143 uLCD.filled_rectangle(Z[0][0],Z[0][1],Z[0][0]+2,Z[0][1]+2,GREEN);
rjones75 10:9d16de327719 144
rjones75 10:9d16de327719 145 //Game starts here
rjones75 10:9d16de327719 146 while(state==playing) {
rjones75 10:9d16de327719 147
rjones75 10:9d16de327719 148 //Player Movement
rjones75 10:9d16de327719 149 //Move the player when buttons are pressed (but don't go off the screen)
rjones75 10:9d16de327719 150 if(myNav.up() && (Py1!=0)) {
rjones75 10:9d16de327719 151 facing=up;
rjones75 10:9d16de327719 152 Py1--;
rjones75 10:9d16de327719 153 Py2--;
rjones75 10:9d16de327719 154 uLCD.filled_rectangle(Px1,Py1,Px2,Py2,BLUE);
rjones75 10:9d16de327719 155 uLCD.filled_rectangle(Px1,Py2+1,Px2,Py2+1,BLACK);
rjones75 10:9d16de327719 156 } else if(myNav.down() && (Py2!=127)) {
rjones75 10:9d16de327719 157 facing=down;
rjones75 10:9d16de327719 158 Py1++;
rjones75 10:9d16de327719 159 Py2++;
rjones75 10:9d16de327719 160 uLCD.filled_rectangle(Px1,Py1,Px2,Py2,BLUE);
rjones75 10:9d16de327719 161 uLCD.filled_rectangle(Px1,Py1-1,Px2,Py1-1,BLACK);
rjones75 10:9d16de327719 162 } else if(myNav.left() && (Px1!=0)) {
rjones75 10:9d16de327719 163 facing=left;
rjones75 10:9d16de327719 164 Px1--;
rjones75 10:9d16de327719 165 Px2--;
rjones75 10:9d16de327719 166 uLCD.filled_rectangle(Px1,Py1,Px2,Py2,BLUE);
rjones75 10:9d16de327719 167 uLCD.filled_rectangle(Px2+1,Py1,Px2+1,Py2,BLACK);
rjones75 10:9d16de327719 168 } else if(myNav.right() && (Px2!=127)) {
rjones75 10:9d16de327719 169 facing=right;
rjones75 10:9d16de327719 170 Px1++;
rjones75 10:9d16de327719 171 Px2++;
rjones75 10:9d16de327719 172 uLCD.filled_rectangle(Px1,Py1,Px2,Py2,BLUE);
rjones75 10:9d16de327719 173 uLCD.filled_rectangle(Px1-1,Py1,Px1-1,Py2,BLACK);
rjones75 10:9d16de327719 174 }
rjones75 10:9d16de327719 175 //Firing the gun depending on where you are facing
rjones75 10:9d16de327719 176 if(myNav.fire() && facing==up && BUy==0) {
rjones75 10:9d16de327719 177 BUx=Px1+1;
rjones75 10:9d16de327719 178 BUy=Py1-1;
rjones75 10:9d16de327719 179 uLCD.pixel(BUx,BUy,WHITE);
rjones75 10:9d16de327719 180 } else if(myNav.fire() && facing==down && BDy==127) {
rjones75 10:9d16de327719 181 BDx=Px1+1;
rjones75 10:9d16de327719 182 BDy=Py2+1;
rjones75 10:9d16de327719 183 uLCD.pixel(BDx,BDy,WHITE);
rjones75 10:9d16de327719 184 } else if(myNav.fire() && facing==left && BLx==0) {
rjones75 10:9d16de327719 185 BLx=Px1-1;
rjones75 10:9d16de327719 186 BLy=Py2-1;
rjones75 10:9d16de327719 187 uLCD.pixel(BLx,BLy,WHITE);
rjones75 10:9d16de327719 188 } else if(myNav.fire() && facing==right && BRx==127) {
rjones75 10:9d16de327719 189 BRx=Px2+1;
rjones75 10:9d16de327719 190 BRy=Py2-1;
rjones75 10:9d16de327719 191 uLCD.pixel(BRx,BRy,WHITE);
rjones75 10:9d16de327719 192 }
rjones75 10:9d16de327719 193 //Keep moving the bullets until they hit the wall or a zombie
rjones75 10:9d16de327719 194 if(BUy!=0 && !hitU) {
rjones75 10:9d16de327719 195 BUy--;
rjones75 10:9d16de327719 196 uLCD.pixel(BUx,BUy,WHITE);
rjones75 10:9d16de327719 197 uLCD.pixel(BUx,BUy+1,BLACK);
rjones75 10:9d16de327719 198 //Hit detection
rjones75 10:9d16de327719 199 for(int i=0; i<3; i++) {
rjones75 10:9d16de327719 200 for(int j=0; j<3; j++) {
rjones75 10:9d16de327719 201 if((Z[0][0]+i)==BUx && (Z[0][1]+j)==BUy) {
rjones75 10:9d16de327719 202 hitU=true;
rjones75 10:9d16de327719 203 }
rjones75 10:9d16de327719 204 }
rjones75 10:9d16de327719 205 }
rjones75 10:9d16de327719 206 } else {
rjones75 10:9d16de327719 207 uLCD.filled_rectangle(BUx-2,BUy-2,BUx+2,BUy+1,BLACK);
rjones75 10:9d16de327719 208 BUy=0;
rjones75 10:9d16de327719 209 hitU=false;
rjones75 10:9d16de327719 210 }
rjones75 10:9d16de327719 211 if(BDy!=127 && !hitD) {
rjones75 10:9d16de327719 212 BDy++;
rjones75 10:9d16de327719 213 uLCD.pixel(BDx,BDy,WHITE);
rjones75 10:9d16de327719 214 uLCD.pixel(BDx,BDy-1,BLACK);
rjones75 10:9d16de327719 215 //Hit detection
rjones75 10:9d16de327719 216 for(int i=0; i<3; i++) {
rjones75 10:9d16de327719 217 for(int j=0; j<3; j++) {
rjones75 10:9d16de327719 218 if((Z[0][0]+i)==BDx && (Z[0][1]+j)==BDy) {
rjones75 10:9d16de327719 219 hitD=true;
rjones75 10:9d16de327719 220 }
rjones75 10:9d16de327719 221 }
rjones75 10:9d16de327719 222 }
rjones75 10:9d16de327719 223 } else {
rjones75 10:9d16de327719 224 uLCD.filled_rectangle(BDx-2,BDy-1,BDx+2,BDy+2,BLACK);
rjones75 10:9d16de327719 225 BDy=127;
rjones75 10:9d16de327719 226 hitD=false;
rjones75 10:9d16de327719 227 }
rjones75 10:9d16de327719 228 if(BLx!=0 && !hitL) {
rjones75 10:9d16de327719 229 BLx--;
rjones75 10:9d16de327719 230 uLCD.pixel(BLx,BLy,WHITE);
rjones75 10:9d16de327719 231 uLCD.pixel(BLx+1,BLy,BLACK);
rjones75 10:9d16de327719 232 //Hit detection
rjones75 10:9d16de327719 233 for(int i=0; i<3; i++) {
rjones75 10:9d16de327719 234 for(int j=0; j<3; j++) {
rjones75 10:9d16de327719 235 if((Z[0][0]+i)==BLx && (Z[0][1]+j)==BLy) {
rjones75 10:9d16de327719 236 hitL=true;
rjones75 10:9d16de327719 237 }
rjones75 10:9d16de327719 238 }
rjones75 10:9d16de327719 239 }
rjones75 10:9d16de327719 240 } else {
rjones75 10:9d16de327719 241 uLCD.filled_rectangle(BLx-2,BLy-2,BLx+1,BLy+2,BLACK);
rjones75 10:9d16de327719 242 BLx=0;
rjones75 10:9d16de327719 243 hitL=false;
rjones75 10:9d16de327719 244 }
rjones75 10:9d16de327719 245 if(BRx!=127 && !hitR) {
rjones75 10:9d16de327719 246 BRx++;
rjones75 10:9d16de327719 247 uLCD.pixel(BRx,BRy,WHITE);
rjones75 10:9d16de327719 248 uLCD.pixel(BRx-1,BRy,BLACK);
rjones75 10:9d16de327719 249 //Hit detection
rjones75 10:9d16de327719 250 for(int i=0; i<3; i++) {
rjones75 10:9d16de327719 251 for(int j=0; j<3; j++) {
rjones75 10:9d16de327719 252 if((Z[0][0]+i)==BRx && (Z[0][1]+j)==BRy) {
rjones75 10:9d16de327719 253 hitR=true;
rjones75 10:9d16de327719 254 }
rjones75 10:9d16de327719 255 }
rjones75 10:9d16de327719 256 }
rjones75 10:9d16de327719 257 } else {
rjones75 10:9d16de327719 258 uLCD.filled_rectangle(BRx-1,BRy-2,BRx+2,BRy+2,BLACK);
rjones75 10:9d16de327719 259 BRx=127;
rjones75 10:9d16de327719 260 hitR=false;
rjones75 10:9d16de327719 261 }
rjones75 10:9d16de327719 262
rjones75 10:9d16de327719 263
rjones75 10:9d16de327719 264 //Zombie Movement
rjones75 10:9d16de327719 265 if(!hitU && !hitD && !hitL && !hitR) {
rjones75 10:9d16de327719 266 if(Px1 > (Z[0][0]+2)) {
rjones75 10:9d16de327719 267 Z[0][0]=Z[0][0]+1;
rjones75 10:9d16de327719 268 uLCD.filled_rectangle(Z[0][0]-1,Z[0][1],Z[0][0]-1,Z[0][1]+2,BLACK);
rjones75 10:9d16de327719 269 } else if(Px2 < Z[0][0]) {
rjones75 10:9d16de327719 270 Z[0][0]--;
rjones75 10:9d16de327719 271 uLCD.filled_rectangle(Z[0][0]+3,Z[0][1],Z[0][0]+3,Z[0][1]+2,BLACK);
rjones75 10:9d16de327719 272 }
rjones75 10:9d16de327719 273 if(Py1 > Z[0][1]+2) {
rjones75 10:9d16de327719 274 Z[0][1]++;
rjones75 10:9d16de327719 275 uLCD.filled_rectangle(Z[0][0],Z[0][1]-1,Z[0][0]+2,Z[0][1]-1,BLACK);
rjones75 10:9d16de327719 276 } else if(Py2 < Z[0][1]) {
rjones75 10:9d16de327719 277 Z[0][1]--;
rjones75 10:9d16de327719 278 uLCD.filled_rectangle(Z[0][0],Z[0][1]+3,Z[0][0]+2,Z[0][1]+3,BLACK);
rjones75 10:9d16de327719 279 }
rjones75 10:9d16de327719 280 uLCD.filled_rectangle(Z[0][0],Z[0][1],Z[0][0]+2,Z[0][1]+2,GREEN);
rjones75 10:9d16de327719 281 }
rjones75 10:9d16de327719 282 //If zombie is hit, add 10 points and move the zombie to a random spot outside of the
rjones75 10:9d16de327719 283 //map that doesn't hit (0,0) or (127,127), which is where the bullets are held
rjones75 10:9d16de327719 284 if(hitU || hitD || hitL || hitR) {
rjones75 10:9d16de327719 285 score += 10;
rjones75 10:9d16de327719 286 if(rand() % 2) {
rjones75 10:9d16de327719 287 Z[0][0] = (rand() % 120)+1;
rjones75 10:9d16de327719 288 if(rand() % 2)
rjones75 10:9d16de327719 289 Z[0][1] = -3;
rjones75 10:9d16de327719 290 else
rjones75 10:9d16de327719 291 Z[0][1] = 128;
rjones75 10:9d16de327719 292 } else {
rjones75 10:9d16de327719 293 Z[0][1] = (rand() % 120)+1;
rjones75 10:9d16de327719 294 if(rand() % 2)
rjones75 10:9d16de327719 295 Z[0][0] = -3;
rjones75 10:9d16de327719 296 else
rjones75 10:9d16de327719 297 Z[0][0] = 128;
rjones75 10:9d16de327719 298 }
rjones75 10:9d16de327719 299 }
rjones75 10:9d16de327719 300 //Check if zombie touches player, resulting in game over
rjones75 10:9d16de327719 301 for(int i=0; i<3; i++) {
rjones75 10:9d16de327719 302 for(int j=0; j<3; j++) {
rjones75 10:9d16de327719 303 if((Z[0][0]+i)==Px1+j) {
rjones75 10:9d16de327719 304 for(int m=0; m<3; m++) {
rjones75 10:9d16de327719 305 for(int n=0; n<3; n++) {
rjones75 10:9d16de327719 306 if((Z[0][1]+m)==Py1+j) {
rjones75 10:9d16de327719 307 state=gameover;
rjones75 10:9d16de327719 308 break;
rjones75 10:9d16de327719 309 }
rjones75 10:9d16de327719 310 }
rjones75 10:9d16de327719 311 }
rjones75 10:9d16de327719 312 }
rjones75 10:9d16de327719 313 }
rjones75 10:9d16de327719 314 }
rjones75 10:9d16de327719 315 //Display score in the top
rjones75 10:9d16de327719 316 uLCD.locate(6,0);
rjones75 10:9d16de327719 317 uLCD.printf("Score: %d",score);
rjones75 10:9d16de327719 318 }
rjones75 10:9d16de327719 319 //Display Game Over Screen
rjones75 10:9d16de327719 320 uLCD.media_init();
rjones75 10:9d16de327719 321 uLCD.set_sector_address(0x001D, 0x4C65);
rjones75 10:9d16de327719 322 uLCD.display_image(0,0);
rjones75 10:9d16de327719 323 //Reset when FIRE is pressed
rjones75 10:9d16de327719 324 while(state==gameover) {
rjones75 10:9d16de327719 325 if(myNav.fire()) {
rjones75 10:9d16de327719 326 uLCD.cls();
rjones75 10:9d16de327719 327 wait(1.0);
rjones75 10:9d16de327719 328 state=start;
rjones75 10:9d16de327719 329 }
rjones75 10:9d16de327719 330 }
rjones75 10:9d16de327719 331 }
rjones75 10:9d16de327719 332
rjones75 10:9d16de327719 333 }
rjones75 10:9d16de327719 334
rjones75 10:9d16de327719 335
rjones75 10:9d16de327719 336