Wall dodging game utilising a joystick and Nokia 5110 LCD display

Dependencies:   N5110 mbed

Committer:
el14moh
Date:
Sun Apr 24 16:17:55 2016 +0000
Revision:
9:ca800196baeb
Parent:
8:b49e0cc362f2
Child:
10:dd2886f3ac0a
Stop making changes.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
el14moh 0:6b29f9c29a2a 1 /* Joystick
el14moh 0:6b29f9c29a2a 2 Max Hamilton
el14moh 0:6b29f9c29a2a 3
el14moh 0:6b29f9c29a2a 4 My project will be designing a game in which the player must avoid a number
el14moh 0:6b29f9c29a2a 5 of obstacles coming from different locations for as long as possible
el14moh 0:6b29f9c29a2a 6
el14moh 0:6b29f9c29a2a 7 Week 19 Code - Initial test of mbed screen and initilisations
el14moh 0:6b29f9c29a2a 8 Week 20 Code - Add code to move a player controlled ball around the screen
el14moh 0:6b29f9c29a2a 9 Week 21 Code - Add code to generate and move an obstacle down the screen
el14moh 0:6b29f9c29a2a 10
el14moh 0:6b29f9c29a2a 11 Week 22 Code - Significant progress over easter holiday
el14moh 0:6b29f9c29a2a 12 - Diagonal directions added to joystick
el14moh 0:6b29f9c29a2a 13 - Collisions implemented. Game over triggers if character hits a wall
el14moh 0:6b29f9c29a2a 14 - Walls/obstacles developed greatly
el14moh 0:6b29f9c29a2a 15 - Obstacle extended into full wall. Wall structs created and walls travel from all sides of the screen
el14moh 0:6b29f9c29a2a 16 - Walls start of appearing from one side of the screen. As time goes on, more will appear from differnt sides, with multiple walls on screen at once
el14moh 0:6b29f9c29a2a 17 - Cooldown added to walls to ensure a new one will not instantly appear from a side that another wall has just travelled to.
el14moh 0:6b29f9c29a2a 18 - visual warning on screen when walls are about to appear from a new direction
el14moh 0:6b29f9c29a2a 19 - Game now keeps track of score and displays it at the end of the game
el14moh 0:6b29f9c29a2a 20 - Intro screen added
el14moh 0:6b29f9c29a2a 21
el14moh 3:8890b4605a10 22 Week 23 Code - Brief invincibility added by pressing joybutton
el14moh 3:8890b4605a10 23 - invincibilty limit added, indicators added to the side
el14moh 3:8890b4605a10 24 - game loops succesfully
el14moh 7:ca18e8775d8d 25 - Menu added with 4 options
el14moh 7:ca18e8775d8d 26 - DodgeMILD, start the game easy with one wall
el14moh 7:ca18e8775d8d 27 - DodgeMANIA, start the game hard with all four walls
el14moh 7:ca18e8775d8d 28 - Help, get instructions on the game
el14moh 7:ca18e8775d8d 29 - Scores, see the top 3 highscore, will be used for saved scores if SD card is implemented
el14moh 3:8890b4605a10 30
el14moh 3:8890b4605a10 31 NOTES - top wall collision seems to be off
el14moh 7:ca18e8775d8d 32 - horizontal walls still seem to go beyond the left border occasinanly
el14moh 2:602e9bb053a0 33
el14moh 0:6b29f9c29a2a 34 */
el14moh 0:6b29f9c29a2a 35
el14moh 0:6b29f9c29a2a 36 #include "mbed.h"
el14moh 0:6b29f9c29a2a 37 #include "N5110.h"
el14moh 0:6b29f9c29a2a 38 #include "tones.h"
el14moh 0:6b29f9c29a2a 39
el14moh 0:6b29f9c29a2a 40 #define DIRECTION_TOLERANCE 0.05 // tolerance of joystick direction
el14moh 0:6b29f9c29a2a 41 #define PLAYERRADIUS 2 // size of player ball
el14moh 8:b49e0cc362f2 42 #define MUTE 0 // 0 - buzzer plays, 1 - buzzer muted
el14moh 0:6b29f9c29a2a 43
el14moh 0:6b29f9c29a2a 44 // VCC, SCE, RST, D/C, MOSI, SCLK, LED
el14moh 0:6b29f9c29a2a 45 N5110 lcd (PTD3 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3);
el14moh 0:6b29f9c29a2a 46
el14moh 5:c64d8ba051e9 47 AnalogIn backlight(PTB2); // pot to control brightness
el14moh 0:6b29f9c29a2a 48 DigitalIn button(PTB3); // joystick button object
el14moh 0:6b29f9c29a2a 49 AnalogIn xPot(PTB11); // joystick x direction object
el14moh 0:6b29f9c29a2a 50 AnalogIn yPot(PTB10); // joystick y direction object
el14moh 8:b49e0cc362f2 51 PwmOut buzzer(PTA2); // buzzer object
el14moh 2:602e9bb053a0 52 InterruptIn flick (PTB3); // interruptin instance of button
el14moh 0:6b29f9c29a2a 53
el14moh 0:6b29f9c29a2a 54 Ticker pollJoystick; // timer to regularly read the joystick
el14moh 6:153680563027 55 Ticker menu_pollJoystick; // slower ticker to move joystick through menu
el14moh 0:6b29f9c29a2a 56 Ticker game_timer; // timer to regularly update the screen
el14moh 0:6b29f9c29a2a 57
el14moh 0:6b29f9c29a2a 58 Serial serial(USBTX,USBRX); // Serial for debug
el14moh 0:6b29f9c29a2a 59
el14moh 0:6b29f9c29a2a 60 // create enumerated type (0,1,2,3 etc. for direction)
el14moh 0:6b29f9c29a2a 61 enum DirectionName {
el14moh 0:6b29f9c29a2a 62 UP,
el14moh 0:6b29f9c29a2a 63 DOWN,
el14moh 0:6b29f9c29a2a 64 LEFT,
el14moh 0:6b29f9c29a2a 65 RIGHT,
el14moh 0:6b29f9c29a2a 66 UPRIGHT, // Diagonally up + right
el14moh 0:6b29f9c29a2a 67 UPLEFT, // Diagonally up + left
el14moh 0:6b29f9c29a2a 68 DOWNRIGHT, // Diagonally down + right
el14moh 0:6b29f9c29a2a 69 DOWNLEFT, // Diagonally down + left
el14moh 0:6b29f9c29a2a 70 CENTRE,
el14moh 0:6b29f9c29a2a 71 UNKNOWN
el14moh 0:6b29f9c29a2a 72 };
el14moh 0:6b29f9c29a2a 73
el14moh 0:6b29f9c29a2a 74 typedef struct JoyStick Joystick; // struct for Joystick
el14moh 0:6b29f9c29a2a 75 typedef struct Wall Wall; // struct for Walls
el14moh 6:153680563027 76 typedef const struct State STyp;
el14moh 6:153680563027 77 typedef struct Highscore Highscore;
el14moh 0:6b29f9c29a2a 78
el14moh 0:6b29f9c29a2a 79 struct JoyStick {
el14moh 0:6b29f9c29a2a 80 float x; // current x value
el14moh 0:6b29f9c29a2a 81 float x0; // 'centred' x value
el14moh 0:6b29f9c29a2a 82 float y; // current y value
el14moh 0:6b29f9c29a2a 83 float y0; // 'centred' y value
el14moh 0:6b29f9c29a2a 84 int button; // button state (assume pull-down used, so 1 = pressed, 0 = unpressed)
el14moh 0:6b29f9c29a2a 85 DirectionName direction; // current direction
el14moh 0:6b29f9c29a2a 86 };
el14moh 0:6b29f9c29a2a 87
el14moh 0:6b29f9c29a2a 88 struct Wall {
el14moh 0:6b29f9c29a2a 89 int x; // x-coordinate of wall (realtive to centre of the gap)
el14moh 0:6b29f9c29a2a 90 int y; // y-coordinate of wall (relative to centre of the gap)
el14moh 0:6b29f9c29a2a 91 DirectionName direction; // Direction the wall travels in
el14moh 0:6b29f9c29a2a 92 int random; // randomly generated integer to determine when a wall begins to travel
el14moh 0:6b29f9c29a2a 93 int cooldown; // stops a wall respawning before a certain amount of time
el14moh 1:26ebbb94cf36 94 volatile bool moveFlag; // flag to determine if wall is on screen
el14moh 1:26ebbb94cf36 95 volatile bool genFlag; // flag to determine if wall has been generated
el14moh 0:6b29f9c29a2a 96 };
el14moh 0:6b29f9c29a2a 97
el14moh 6:153680563027 98 struct State {
el14moh 6:153680563027 99 int output; // output value for current state
el14moh 6:153680563027 100 int next_state[3]; // next state (depending on direction 0 - UP, 1 - DOWN)
el14moh 6:153680563027 101 };
el14moh 6:153680563027 102
el14moh 6:153680563027 103 struct Highscore {
el14moh 6:153680563027 104 int one;
el14moh 6:153680563027 105 int two;
el14moh 6:153680563027 106 int three;
el14moh 6:153680563027 107 };
el14moh 6:153680563027 108
el14moh 6:153680563027 109 STyp fsm[4] = {
el14moh 6:153680563027 110 {1,{0,1,0}},
el14moh 6:153680563027 111 {2,{1,2,0}},
el14moh 6:153680563027 112 {4,{2,3,1}},
el14moh 6:153680563027 113 {8,{3,3,2}}
el14moh 6:153680563027 114 };
el14moh 6:153680563027 115
el14moh 0:6b29f9c29a2a 116 // struct variable for joystick
el14moh 0:6b29f9c29a2a 117 Joystick joystick;
el14moh 0:6b29f9c29a2a 118 // struct variable for moving walls
el14moh 0:6b29f9c29a2a 119 Wall leftwall;
el14moh 0:6b29f9c29a2a 120 Wall rightwall;
el14moh 0:6b29f9c29a2a 121 Wall downwall;
el14moh 0:6b29f9c29a2a 122 Wall upwall;
el14moh 0:6b29f9c29a2a 123
el14moh 6:153680563027 124 Highscore hiscore;
el14moh 6:153680563027 125
el14moh 0:6b29f9c29a2a 126 void calibrateJoystick(); // read default positions of the joystick to calibrate later readings
el14moh 0:6b29f9c29a2a 127 void updateJoystick(); // reads direction the joystick has been moved
el14moh 0:6b29f9c29a2a 128 void initDisplay(); // initialises the LCD display
el14moh 0:6b29f9c29a2a 129 void game_timer_isr(); // sets flag for timer interrupt
el14moh 7:ca18e8775d8d 130 void initGame();
el14moh 0:6b29f9c29a2a 131 void moveBall(); // reads joystick direction and moves position of the player
el14moh 0:6b29f9c29a2a 132 void moveWall(); // moves walls along the screen
el14moh 2:602e9bb053a0 133 void invincible(); // makes player briefly invincible
el14moh 2:602e9bb053a0 134 void checkWallCollision(); // checks for any collisions with wall
el14moh 2:602e9bb053a0 135 void checkBorderCollision(); // checks for any collisions with border
el14moh 0:6b29f9c29a2a 136 void updateScreen(); // refreshes the screen, redraws player and walls
el14moh 0:6b29f9c29a2a 137 void warning(); // flashes screen when a new wall is ready to appear
el14moh 7:ca18e8775d8d 138 void initSerial(); // sets baud rate for serial
el14moh 0:6b29f9c29a2a 139 void debug(); // prints for debug purposes
el14moh 2:602e9bb053a0 140 void button_isr();
el14moh 6:153680563027 141 void blink(); // function to make screen flash (do not put in isr unless breaking the loop)
el14moh 6:153680563027 142 void printHelp(); // prints game help
el14moh 6:153680563027 143 void printScores();
el14moh 6:153680563027 144 void draw_border();
el14moh 6:153680563027 145 void calculateHighscores();
el14moh 6:153680563027 146 void initHiscores();
el14moh 8:b49e0cc362f2 147 void playNote(int freq, float time);
el14moh 0:6b29f9c29a2a 148
el14moh 6:153680563027 149 //float refresh_rate = 20; // how often to update display (Hz)
el14moh 6:153680563027 150 //float g_dt = 1.0F/refresh_rate; // global to store time step (F makes it a float, gets rid of compiler warning)
el14moh 0:6b29f9c29a2a 151 volatile int g_timer_flag = 0; // flag for timer interrupt
el14moh 2:602e9bb053a0 152 volatile int game_over_flag = 0; // flag to signal game over
el14moh 2:602e9bb053a0 153 volatile int g_button_flag = 0;
el14moh 0:6b29f9c29a2a 154 int printFlag = 0; // flag for printing
el14moh 6:153680563027 155 volatile int game_start_flag = 0; // flag to start the game
el14moh 3:8890b4605a10 156 int i; // x-coordinate value of player
el14moh 3:8890b4605a10 157 int j; // y-coordinate value of player
el14moh 0:6b29f9c29a2a 158 int counter = 0; // number of times code has looped
el14moh 2:602e9bb053a0 159 volatile bool mortal = 1;
el14moh 2:602e9bb053a0 160 int invun_cool = 0;
el14moh 2:602e9bb053a0 161 int saves = 5;
el14moh 6:153680563027 162 int joyspeed = 5;
el14moh 7:ca18e8775d8d 163 int score = 0;
el14moh 0:6b29f9c29a2a 164
el14moh 6:153680563027 165 int direction;
el14moh 6:153680563027 166 int state;
el14moh 6:153680563027 167 int output;
el14moh 0:6b29f9c29a2a 168
el14moh 0:6b29f9c29a2a 169 int main()
el14moh 0:6b29f9c29a2a 170 {
el14moh 7:ca18e8775d8d 171 initSerial();
el14moh 8:b49e0cc362f2 172 srand(time(NULL)); // generate seed for random number generation
el14moh 0:6b29f9c29a2a 173 calibrateJoystick();
el14moh 0:6b29f9c29a2a 174 initDisplay();
el14moh 6:153680563027 175 initHiscores();
el14moh 0:6b29f9c29a2a 176
el14moh 0:6b29f9c29a2a 177 wait (1.0);
el14moh 0:6b29f9c29a2a 178
el14moh 6:153680563027 179 flick.rise(&button_isr);
el14moh 6:153680563027 180 flick.mode(PullDown);
el14moh 0:6b29f9c29a2a 181
el14moh 3:8890b4605a10 182 lcd.printString("Dodgemania",13,2); // Print game title on screen
el14moh 3:8890b4605a10 183 wait (2.5);
el14moh 3:8890b4605a10 184 for (int z=0; z<88; z++) {
el14moh 3:8890b4605a10 185 lcd.drawCircle(z,20,4,1);
el14moh 0:6b29f9c29a2a 186
el14moh 3:8890b4605a10 187 lcd.clearPixel(z-3,16);
el14moh 3:8890b4605a10 188 lcd.clearPixel(z-4,17);
el14moh 3:8890b4605a10 189 lcd.clearPixel(z-4,18);
el14moh 3:8890b4605a10 190 lcd.clearPixel(z-5,19);
el14moh 3:8890b4605a10 191 lcd.clearPixel(z-5,20);
el14moh 3:8890b4605a10 192 lcd.clearPixel(z-5,21);
el14moh 3:8890b4605a10 193 lcd.clearPixel(z-4,22);
el14moh 3:8890b4605a10 194 lcd.clearPixel(z-4,23);
el14moh 3:8890b4605a10 195 lcd.clearPixel(z-3,24);
el14moh 3:8890b4605a10 196 lcd.refresh();
el14moh 3:8890b4605a10 197 wait(0.01);
el14moh 3:8890b4605a10 198 }
el14moh 0:6b29f9c29a2a 199
el14moh 3:8890b4605a10 200 lcd.clear();
el14moh 3:8890b4605a10 201 wait(0.5);
el14moh 0:6b29f9c29a2a 202
el14moh 6:153680563027 203 blink();
el14moh 3:8890b4605a10 204
el14moh 3:8890b4605a10 205 while(1) {
el14moh 9:ca800196baeb 206 g_button_flag = 0;
el14moh 0:6b29f9c29a2a 207
el14moh 6:153680563027 208 joyspeed = 10;
el14moh 6:153680563027 209 game_timer.detach();
el14moh 6:153680563027 210 game_timer.attach(&game_timer_isr,1.0/joyspeed);
el14moh 6:153680563027 211
el14moh 6:153680563027 212 pollJoystick.detach();
el14moh 6:153680563027 213 pollJoystick.attach(&updateJoystick,1.0/joyspeed); // read joystick (JOYSPEED) times per second
el14moh 6:153680563027 214
el14moh 6:153680563027 215 state = 0;
el14moh 6:153680563027 216
el14moh 0:6b29f9c29a2a 217
el14moh 6:153680563027 218 while(game_start_flag == 0) // ticker interrupt
el14moh 6:153680563027 219 if (g_timer_flag) {
el14moh 6:153680563027 220 g_timer_flag = 0; // clear flag
el14moh 9:ca800196baeb 221
el14moh 6:153680563027 222 if (joystick.direction == UP) {
el14moh 6:153680563027 223 direction = 2;
el14moh 6:153680563027 224 } else if (joystick.direction == DOWN) {
el14moh 6:153680563027 225 direction = 1;
el14moh 6:153680563027 226 } else {
el14moh 6:153680563027 227 direction = 0;
el14moh 6:153680563027 228 }
el14moh 9:ca800196baeb 229
el14moh 6:153680563027 230 output = fsm[state].output;
el14moh 6:153680563027 231 state = fsm[state].next_state[direction];
el14moh 0:6b29f9c29a2a 232
el14moh 6:153680563027 233 lcd.clear();
el14moh 6:153680563027 234
el14moh 6:153680563027 235 lcd.printString("Dodgemild",12,1);
el14moh 6:153680563027 236 lcd.printString("DodgeMANIA!",12,2);
el14moh 6:153680563027 237 lcd.printString("Help",12,3);
el14moh 6:153680563027 238 lcd.printString("Scores",12,4);
el14moh 0:6b29f9c29a2a 239
el14moh 6:153680563027 240 if (output == 1) {
el14moh 6:153680563027 241 lcd.drawCircle(6,11,2,1);
el14moh 6:153680563027 242 } else if (output == 2) {
el14moh 6:153680563027 243 lcd.drawCircle(6,19,2,1);
el14moh 6:153680563027 244 } else if (output == 4) {
el14moh 6:153680563027 245 lcd.drawCircle(6,27,2,1);
el14moh 6:153680563027 246 } else {
el14moh 6:153680563027 247 lcd.drawCircle(6,35,2,1);
el14moh 6:153680563027 248 }
el14moh 6:153680563027 249 lcd.refresh();
el14moh 9:ca800196baeb 250
el14moh 9:ca800196baeb 251 if (((direction == 1)&&(output != 8))||((direction == 2)&&(output != 1))) {
el14moh 9:ca800196baeb 252 playNote(NOTE_G2,0.05);
el14moh 9:ca800196baeb 253 }
el14moh 0:6b29f9c29a2a 254
el14moh 6:153680563027 255 if (g_button_flag) {
el14moh 6:153680563027 256 if (output == 1) {
el14moh 9:ca800196baeb 257 g_button_flag = 0;
el14moh 9:ca800196baeb 258 playNote(NOTE_B2,0.1);
el14moh 7:ca18e8775d8d 259 initGame();
el14moh 6:153680563027 260 game_start_flag = 1;
el14moh 6:153680563027 261 } else if (output == 2) {
el14moh 9:ca800196baeb 262 g_button_flag = 0;
el14moh 9:ca800196baeb 263 playNote(NOTE_B2,0.1);
el14moh 7:ca18e8775d8d 264 initGame();
el14moh 6:153680563027 265 counter = 1501;
el14moh 6:153680563027 266 game_start_flag = 1;
el14moh 6:153680563027 267 } else if (output == 4) {
el14moh 9:ca800196baeb 268 g_button_flag = 0;
el14moh 9:ca800196baeb 269 playNote(NOTE_B2,0.1);
el14moh 6:153680563027 270 blink();
el14moh 6:153680563027 271 lcd.clear();
el14moh 6:153680563027 272 printHelp();
el14moh 6:153680563027 273 } else if (output == 8) {
el14moh 9:ca800196baeb 274 g_button_flag = 0;
el14moh 9:ca800196baeb 275 playNote(NOTE_B2,0.1);
el14moh 6:153680563027 276 blink();
el14moh 6:153680563027 277 lcd.clear();
el14moh 6:153680563027 278 printScores();
el14moh 6:153680563027 279 }
el14moh 6:153680563027 280 }
el14moh 6:153680563027 281 }
el14moh 6:153680563027 282 blink();
el14moh 6:153680563027 283 lcd.clear();
el14moh 6:153680563027 284 // Draw game border
el14moh 6:153680563027 285 draw_border();
el14moh 6:153680563027 286 // Countdown
el14moh 0:6b29f9c29a2a 287 wait(0.5);
el14moh 0:6b29f9c29a2a 288 lcd.printString("3",40,2);
el14moh 8:b49e0cc362f2 289 playNote(NOTE_C4,0.2);
el14moh 8:b49e0cc362f2 290 wait(0.3);
el14moh 0:6b29f9c29a2a 291 lcd.drawRect(10,10,64,28,2);
el14moh 0:6b29f9c29a2a 292 lcd.refresh();
el14moh 0:6b29f9c29a2a 293 wait(0.5);
el14moh 0:6b29f9c29a2a 294 lcd.printString("2",40,2);
el14moh 8:b49e0cc362f2 295 playNote(NOTE_C4,0.2);
el14moh 8:b49e0cc362f2 296 wait(0.3);
el14moh 0:6b29f9c29a2a 297 lcd.drawRect(10,10,64,28,2);
el14moh 0:6b29f9c29a2a 298 lcd.refresh();
el14moh 0:6b29f9c29a2a 299 wait(0.5);
el14moh 0:6b29f9c29a2a 300 lcd.printString("1",40,2);
el14moh 8:b49e0cc362f2 301 playNote(NOTE_C4,0.2);
el14moh 8:b49e0cc362f2 302 wait(0.3);
el14moh 0:6b29f9c29a2a 303 lcd.drawRect(10,10,64,28,2);
el14moh 0:6b29f9c29a2a 304 lcd.refresh();
el14moh 0:6b29f9c29a2a 305 wait(0.5);
el14moh 0:6b29f9c29a2a 306 lcd.drawRect(10,10,64,28,2);
el14moh 0:6b29f9c29a2a 307 lcd.refresh();
el14moh 0:6b29f9c29a2a 308 lcd.printString("Go!",36,2);
el14moh 8:b49e0cc362f2 309 playNote(NOTE_G4,0.5);
el14moh 0:6b29f9c29a2a 310 lcd.drawRect(10,10,64,28,2);
el14moh 0:6b29f9c29a2a 311 lcd.refresh();
el14moh 0:6b29f9c29a2a 312
el14moh 6:153680563027 313 joyspeed = 20;
el14moh 6:153680563027 314 game_timer.detach();
el14moh 6:153680563027 315 game_timer.attach(&game_timer_isr,1.0/joyspeed);
el14moh 6:153680563027 316 pollJoystick.detach();
el14moh 6:153680563027 317 pollJoystick.attach(&updateJoystick,1.0/joyspeed);
el14moh 3:8890b4605a10 318
el14moh 0:6b29f9c29a2a 319 while (game_over_flag == 0) {
el14moh 0:6b29f9c29a2a 320
el14moh 0:6b29f9c29a2a 321 if ( g_timer_flag ) { // ticker interrupt
el14moh 0:6b29f9c29a2a 322 g_timer_flag = 0; // clear flag
el14moh 0:6b29f9c29a2a 323 moveWall();
el14moh 0:6b29f9c29a2a 324 moveBall();
el14moh 2:602e9bb053a0 325 invincible();
el14moh 2:602e9bb053a0 326 checkBorderCollision();
el14moh 9:ca800196baeb 327 checkWallCollision();
el14moh 0:6b29f9c29a2a 328 updateScreen();
el14moh 0:6b29f9c29a2a 329 warning();
el14moh 0:6b29f9c29a2a 330 debug();
el14moh 0:6b29f9c29a2a 331
el14moh 0:6b29f9c29a2a 332 counter++; // increment counter each cycle (approx. 20 points a second)
el14moh 7:ca18e8775d8d 333 score++; // this is seperate from counter for the purposes of keeping score 0 while all walls are present on DodgeMANIA
el14moh 0:6b29f9c29a2a 334
el14moh 0:6b29f9c29a2a 335 // wall cooldowns increased. N.B these are set to 0 when a wall finishes moving
el14moh 0:6b29f9c29a2a 336 leftwall.cooldown++;
el14moh 0:6b29f9c29a2a 337 rightwall.cooldown++;
el14moh 0:6b29f9c29a2a 338 downwall.cooldown++;
el14moh 0:6b29f9c29a2a 339 upwall.cooldown++;
el14moh 0:6b29f9c29a2a 340 }
el14moh 0:6b29f9c29a2a 341 sleep();
el14moh 0:6b29f9c29a2a 342 }
el14moh 0:6b29f9c29a2a 343
el14moh 3:8890b4605a10 344 game_over_flag = 0;
el14moh 3:8890b4605a10 345
el14moh 6:153680563027 346 blink();
el14moh 8:b49e0cc362f2 347 playNote(NOTE_E4,0.1);
el14moh 8:b49e0cc362f2 348 playNote(NOTE_C4,0.1);
el14moh 8:b49e0cc362f2 349 playNote(NOTE_A3,0.1);
el14moh 8:b49e0cc362f2 350 playNote(NOTE_A2,0.3);
el14moh 8:b49e0cc362f2 351 wait(0.8);
el14moh 0:6b29f9c29a2a 352 lcd.clear();
el14moh 0:6b29f9c29a2a 353 wait(0.2);
el14moh 0:6b29f9c29a2a 354
el14moh 6:153680563027 355 calculateHighscores();
el14moh 6:153680563027 356
el14moh 6:153680563027 357 lcd.printString("Game Over!",14,0);
el14moh 0:6b29f9c29a2a 358 lcd.refresh();
el14moh 0:6b29f9c29a2a 359
el14moh 0:6b29f9c29a2a 360 wait(1.0);
el14moh 6:153680563027 361
el14moh 6:153680563027 362 lcd.printString("HiScore:",3,3);
el14moh 6:153680563027 363 lcd.printString("Score:",3,2);
el14moh 6:153680563027 364
el14moh 6:153680563027 365 char score_buffer[14];
el14moh 6:153680563027 366 char hiscore_buffer[14];
el14moh 7:ca18e8775d8d 367 int length_one = sprintf(score_buffer,"%d",score);
el14moh 6:153680563027 368 int length_two = sprintf(hiscore_buffer,"%d",hiscore.one);
el14moh 7:ca18e8775d8d 369 if (score <= 9999) { // 9999 is highest number that fits on screen
el14moh 6:153680563027 370 lcd.printString(score_buffer,54,2);
el14moh 6:153680563027 371 lcd.printString(hiscore_buffer,54,3);
el14moh 0:6b29f9c29a2a 372 } else {
el14moh 6:153680563027 373 lcd.printString ("Wow!",54,2); // if score is too large to fit in box
el14moh 6:153680563027 374 lcd.printString ("Wow!",54,3);
el14moh 0:6b29f9c29a2a 375 }
el14moh 6:153680563027 376
el14moh 0:6b29f9c29a2a 377 lcd.refresh();
el14moh 0:6b29f9c29a2a 378
el14moh 7:ca18e8775d8d 379 if (score >= hiscore.one) {
el14moh 6:153680563027 380 wait(1.0);
el14moh 6:153680563027 381 lcd.printString("HIGHSCORE!",13,5);
el14moh 8:b49e0cc362f2 382 playNote(NOTE_E3,0.1);
el14moh 8:b49e0cc362f2 383 wait(0.1);
el14moh 8:b49e0cc362f2 384 playNote(NOTE_C3,0.05);
el14moh 8:b49e0cc362f2 385 wait(0.05);
el14moh 8:b49e0cc362f2 386 playNote(NOTE_C3,0.05);
el14moh 8:b49e0cc362f2 387 wait(0.05);
el14moh 8:b49e0cc362f2 388 playNote(NOTE_C3,0.05);
el14moh 8:b49e0cc362f2 389 wait(0.15);
el14moh 8:b49e0cc362f2 390 playNote(NOTE_G3,0.1);
el14moh 8:b49e0cc362f2 391 wait(0.1);
el14moh 8:b49e0cc362f2 392 playNote(NOTE_E3,0.1);
el14moh 8:b49e0cc362f2 393 wait(0.1);
el14moh 8:b49e0cc362f2 394 playNote(NOTE_G3,0.1);
el14moh 8:b49e0cc362f2 395 wait(0.1);
el14moh 8:b49e0cc362f2 396 playNote(NOTE_C4,0.5);
el14moh 8:b49e0cc362f2 397 wait(0.1);
el14moh 6:153680563027 398 lcd.printString("CONGRATS!!",13,5);
el14moh 8:b49e0cc362f2 399 playNote(NOTE_E2,0.2);
el14moh 9:ca800196baeb 400
el14moh 6:153680563027 401 } else {
el14moh 8:b49e0cc362f2 402 playNote(NOTE_A2,0.05);
el14moh 8:b49e0cc362f2 403 wait(0.05);
el14moh 8:b49e0cc362f2 404 playNote(NOTE_A2,0.05);
el14moh 8:b49e0cc362f2 405 wait(0.05);
el14moh 8:b49e0cc362f2 406 playNote(NOTE_A2,0.05);
el14moh 8:b49e0cc362f2 407 wait(0.05);
el14moh 8:b49e0cc362f2 408 playNote(NOTE_A2,0.3);
el14moh 6:153680563027 409 }
el14moh 9:ca800196baeb 410 lcd.refresh();
el14moh 9:ca800196baeb 411 while(1) {
el14moh 9:ca800196baeb 412 if (g_button_flag) {
el14moh 9:ca800196baeb 413 g_button_flag = 0;
el14moh 9:ca800196baeb 414 playNote(NOTE_E2,0.1);
el14moh 9:ca800196baeb 415 blink();
el14moh 9:ca800196baeb 416 lcd.clear();
el14moh 9:ca800196baeb 417 break;
el14moh 9:ca800196baeb 418 }
el14moh 9:ca800196baeb 419 }
el14moh 6:153680563027 420 game_start_flag = 0;
el14moh 0:6b29f9c29a2a 421
el14moh 6:153680563027 422 //return 0;
el14moh 0:6b29f9c29a2a 423 }
el14moh 0:6b29f9c29a2a 424
el14moh 0:6b29f9c29a2a 425 }
el14moh 0:6b29f9c29a2a 426
el14moh 2:602e9bb053a0 427 void moveBall() // reads joystick direction and moves position of the player
el14moh 0:6b29f9c29a2a 428 {
el14moh 0:6b29f9c29a2a 429 if (joystick.direction == UP) {
el14moh 0:6b29f9c29a2a 430 j-=1;
el14moh 0:6b29f9c29a2a 431 } else if (joystick.direction == DOWN) {
el14moh 0:6b29f9c29a2a 432 j+=1;
el14moh 0:6b29f9c29a2a 433 } else if (joystick.direction == LEFT) {
el14moh 0:6b29f9c29a2a 434 i-=1;
el14moh 0:6b29f9c29a2a 435 } else if (joystick.direction == RIGHT) {
el14moh 0:6b29f9c29a2a 436 i+=1;
el14moh 0:6b29f9c29a2a 437 } else if (joystick.direction == UPRIGHT) {
el14moh 0:6b29f9c29a2a 438 j-=1;
el14moh 0:6b29f9c29a2a 439 i+=1;
el14moh 0:6b29f9c29a2a 440 } else if (joystick.direction == UPLEFT) {
el14moh 0:6b29f9c29a2a 441 j-=1;
el14moh 0:6b29f9c29a2a 442 i-=1;
el14moh 0:6b29f9c29a2a 443 } else if (joystick.direction == DOWNRIGHT) {
el14moh 0:6b29f9c29a2a 444 j+=1;
el14moh 0:6b29f9c29a2a 445 i+=1;
el14moh 0:6b29f9c29a2a 446 } else if (joystick.direction == DOWNLEFT) {
el14moh 0:6b29f9c29a2a 447 j+=1;
el14moh 0:6b29f9c29a2a 448 i-=1;
el14moh 0:6b29f9c29a2a 449 }
el14moh 0:6b29f9c29a2a 450 }
el14moh 0:6b29f9c29a2a 451
el14moh 2:602e9bb053a0 452 void moveWall() // moves walls along the screen
el14moh 0:6b29f9c29a2a 453 {
el14moh 0:6b29f9c29a2a 454 leftwall.random = rand()%20;
el14moh 0:6b29f9c29a2a 455 rightwall.random = rand()%20;
el14moh 0:6b29f9c29a2a 456 downwall.random = rand()%50;
el14moh 0:6b29f9c29a2a 457 upwall.random = rand()%50;
el14moh 0:6b29f9c29a2a 458
el14moh 0:6b29f9c29a2a 459 // LEFT WALL
el14moh 0:6b29f9c29a2a 460 if (leftwall.moveFlag == 1) { // if wall is moving
el14moh 0:6b29f9c29a2a 461 leftwall.x-=1; // move wall left
el14moh 3:8890b4605a10 462 if (leftwall.x<8) { // if wall hits a border
el14moh 0:6b29f9c29a2a 463 leftwall.moveFlag = 0; // stop wall moving
el14moh 0:6b29f9c29a2a 464 leftwall.cooldown = 0; // reset the cooldown for the wall
el14moh 0:6b29f9c29a2a 465 }
el14moh 0:6b29f9c29a2a 466 } else { // if wall has stopped moving
el14moh 0:6b29f9c29a2a 467 if (leftwall.genFlag == 0) { // if a new wall HASN'T been generated
el14moh 0:6b29f9c29a2a 468 leftwall.y = rand() % 27+8; // make new random y-coordinate
el14moh 0:6b29f9c29a2a 469 leftwall.x = 82; // reset x-coordinate to rightmost position
el14moh 0:6b29f9c29a2a 470 leftwall.genFlag = 1; // wall has been generated
el14moh 0:6b29f9c29a2a 471 } else { // if a new wall HAS been generated
el14moh 0:6b29f9c29a2a 472 if (leftwall.cooldown > 80) { // if a new wall hasnt started moving in 4 seconds, force it to move
el14moh 0:6b29f9c29a2a 473 leftwall.moveFlag = 1;
el14moh 0:6b29f9c29a2a 474 leftwall.genFlag = 0;
el14moh 0:6b29f9c29a2a 475 } else if ((leftwall.random == 1)&&(rightwall.cooldown > 60)) { // if wall starts moving again
el14moh 0:6b29f9c29a2a 476 leftwall.moveFlag = 1; // start wall moving
el14moh 0:6b29f9c29a2a 477 leftwall.genFlag = 0; // clear 'wall generated' flag
el14moh 0:6b29f9c29a2a 478 } else { // else if wall has not started moving again
el14moh 0:6b29f9c29a2a 479 leftwall.moveFlag = 0; // wall is stopped
el14moh 0:6b29f9c29a2a 480 }
el14moh 0:6b29f9c29a2a 481 }
el14moh 0:6b29f9c29a2a 482 }
el14moh 0:6b29f9c29a2a 483
el14moh 0:6b29f9c29a2a 484 // RIGHT WALL
el14moh 0:6b29f9c29a2a 485 if (counter > 200) {
el14moh 0:6b29f9c29a2a 486 if (rightwall.moveFlag == 1) {
el14moh 0:6b29f9c29a2a 487 rightwall.x+=1;
el14moh 0:6b29f9c29a2a 488 if (rightwall.x>80) {
el14moh 0:6b29f9c29a2a 489 rightwall.moveFlag = 0;
el14moh 0:6b29f9c29a2a 490 rightwall.cooldown = 0;
el14moh 0:6b29f9c29a2a 491 }
el14moh 0:6b29f9c29a2a 492 } else {
el14moh 0:6b29f9c29a2a 493 if ((rightwall.genFlag == 0)) {
el14moh 0:6b29f9c29a2a 494 rightwall.y = rand() % 27+8;
el14moh 3:8890b4605a10 495 rightwall.x = 6;
el14moh 0:6b29f9c29a2a 496 rightwall.genFlag = 1;
el14moh 0:6b29f9c29a2a 497 } else {
el14moh 0:6b29f9c29a2a 498 if (rightwall.cooldown > 80) {
el14moh 0:6b29f9c29a2a 499 rightwall.moveFlag = 1;
el14moh 0:6b29f9c29a2a 500 rightwall.genFlag = 0;
el14moh 0:6b29f9c29a2a 501 } else if ((rightwall.random == 1) && (leftwall.cooldown > 60)) {
el14moh 0:6b29f9c29a2a 502 rightwall.moveFlag = 1;
el14moh 0:6b29f9c29a2a 503 rightwall.genFlag = 0;
el14moh 0:6b29f9c29a2a 504 } else {
el14moh 0:6b29f9c29a2a 505 rightwall.moveFlag = 0;
el14moh 0:6b29f9c29a2a 506 }
el14moh 0:6b29f9c29a2a 507 }
el14moh 0:6b29f9c29a2a 508 }
el14moh 0:6b29f9c29a2a 509 }
el14moh 0:6b29f9c29a2a 510
el14moh 0:6b29f9c29a2a 511 // DOWN WALL
el14moh 0:6b29f9c29a2a 512 if (counter > 600) {
el14moh 0:6b29f9c29a2a 513 if (downwall.moveFlag == 1) {
el14moh 0:6b29f9c29a2a 514 if (upwall.cooldown > 60) {
el14moh 0:6b29f9c29a2a 515 if (counter % 2 == 1) { // horizontal walls move half the speed of vertical walls
el14moh 0:6b29f9c29a2a 516 downwall.y+=1;
el14moh 0:6b29f9c29a2a 517 }
el14moh 0:6b29f9c29a2a 518 }
el14moh 0:6b29f9c29a2a 519 if (downwall.y>44) {
el14moh 0:6b29f9c29a2a 520 downwall.moveFlag = 0;
el14moh 0:6b29f9c29a2a 521 }
el14moh 0:6b29f9c29a2a 522 } else {
el14moh 0:6b29f9c29a2a 523 if (downwall.genFlag == 0) {
el14moh 4:d44eace87ab3 524 downwall.x = rand() % 58+13;
el14moh 0:6b29f9c29a2a 525 downwall.y = 1;
el14moh 0:6b29f9c29a2a 526 downwall.genFlag = 1;
el14moh 0:6b29f9c29a2a 527 } else {
el14moh 0:6b29f9c29a2a 528 if (downwall.cooldown > 80) {
el14moh 0:6b29f9c29a2a 529 downwall.moveFlag = 1;
el14moh 0:6b29f9c29a2a 530 downwall.genFlag = 0;
el14moh 0:6b29f9c29a2a 531 } else if ((downwall.random == 1)&&(upwall.cooldown > 60)) {
el14moh 0:6b29f9c29a2a 532 downwall.moveFlag = 1;
el14moh 0:6b29f9c29a2a 533 downwall.genFlag = 0;
el14moh 0:6b29f9c29a2a 534 } else {
el14moh 0:6b29f9c29a2a 535 downwall.moveFlag = 0;
el14moh 0:6b29f9c29a2a 536 }
el14moh 0:6b29f9c29a2a 537 }
el14moh 0:6b29f9c29a2a 538 }
el14moh 0:6b29f9c29a2a 539 }
el14moh 0:6b29f9c29a2a 540
el14moh 0:6b29f9c29a2a 541 // UP WALL
el14moh 0:6b29f9c29a2a 542 if (counter > 1500) {
el14moh 0:6b29f9c29a2a 543 if (upwall.moveFlag == 1) {
el14moh 0:6b29f9c29a2a 544 if (downwall.cooldown > 60) {
el14moh 0:6b29f9c29a2a 545 if (counter % 2 == 1) { // horizontal walls move half the speed of vertical walls
el14moh 0:6b29f9c29a2a 546 upwall.y-=1;
el14moh 0:6b29f9c29a2a 547 }
el14moh 0:6b29f9c29a2a 548 }
el14moh 0:6b29f9c29a2a 549 if (upwall.y<3) {
el14moh 0:6b29f9c29a2a 550 upwall.moveFlag = 0;
el14moh 0:6b29f9c29a2a 551 }
el14moh 0:6b29f9c29a2a 552 } else {
el14moh 0:6b29f9c29a2a 553 if (upwall.genFlag == 0) {
el14moh 4:d44eace87ab3 554 upwall.x = rand() % 58+13;
el14moh 0:6b29f9c29a2a 555 upwall.y = 46;
el14moh 0:6b29f9c29a2a 556 upwall.genFlag = 1;
el14moh 0:6b29f9c29a2a 557 } else {
el14moh 0:6b29f9c29a2a 558 if (upwall.cooldown > 80) {
el14moh 0:6b29f9c29a2a 559 upwall.moveFlag = 1;
el14moh 0:6b29f9c29a2a 560 upwall.genFlag = 0;
el14moh 0:6b29f9c29a2a 561 } else if ((upwall.random == 1)&&(downwall.cooldown > 60)) {
el14moh 0:6b29f9c29a2a 562 upwall.moveFlag = 1;
el14moh 0:6b29f9c29a2a 563 upwall.genFlag = 0;
el14moh 0:6b29f9c29a2a 564 } else {
el14moh 0:6b29f9c29a2a 565 upwall.moveFlag = 0;
el14moh 0:6b29f9c29a2a 566 }
el14moh 0:6b29f9c29a2a 567 }
el14moh 0:6b29f9c29a2a 568 }
el14moh 0:6b29f9c29a2a 569 }
el14moh 0:6b29f9c29a2a 570 }
el14moh 2:602e9bb053a0 571 void checkBorderCollision()
el14moh 0:6b29f9c29a2a 572 {
el14moh 0:6b29f9c29a2a 573 // if floor
el14moh 0:6b29f9c29a2a 574 if ( j >= 47 - (PLAYERRADIUS+3)) {
el14moh 0:6b29f9c29a2a 575 j = 47 - (PLAYERRADIUS+3);
el14moh 0:6b29f9c29a2a 576 }
el14moh 0:6b29f9c29a2a 577
el14moh 0:6b29f9c29a2a 578 // if roof
el14moh 0:6b29f9c29a2a 579 if ( j <= (PLAYERRADIUS+3)) {
el14moh 0:6b29f9c29a2a 580 j = (PLAYERRADIUS+3);
el14moh 0:6b29f9c29a2a 581 }
el14moh 0:6b29f9c29a2a 582
el14moh 0:6b29f9c29a2a 583 // if right wall
el14moh 0:6b29f9c29a2a 584 if ( i >= 83 - (PLAYERRADIUS+3)) {
el14moh 0:6b29f9c29a2a 585 i = 83 - (PLAYERRADIUS+3);
el14moh 0:6b29f9c29a2a 586 }
el14moh 0:6b29f9c29a2a 587
el14moh 0:6b29f9c29a2a 588 // if left wall
el14moh 3:8890b4605a10 589 if ( i <= (PLAYERRADIUS+8)) {
el14moh 3:8890b4605a10 590 i = (PLAYERRADIUS+8);
el14moh 0:6b29f9c29a2a 591 }
el14moh 2:602e9bb053a0 592 }
el14moh 2:602e9bb053a0 593
el14moh 2:602e9bb053a0 594 void invincible()
el14moh 2:602e9bb053a0 595 {
el14moh 2:602e9bb053a0 596 if (g_button_flag) {
el14moh 2:602e9bb053a0 597 g_button_flag = 0;
el14moh 2:602e9bb053a0 598 if ((saves > 0) && (mortal == true)) { // saves are available and not currently used
el14moh 2:602e9bb053a0 599 invun_cool=0;
el14moh 2:602e9bb053a0 600 mortal = false;
el14moh 2:602e9bb053a0 601 invun_cool++;
el14moh 2:602e9bb053a0 602 saves--;
el14moh 2:602e9bb053a0 603 }
el14moh 2:602e9bb053a0 604 }
el14moh 2:602e9bb053a0 605 if (mortal == false) {
el14moh 2:602e9bb053a0 606 invun_cool++;
el14moh 5:c64d8ba051e9 607 if (invun_cool > 30) { // ticker called 20 times per second, therefore 1.5s of invincibility
el14moh 2:602e9bb053a0 608 mortal = true;
el14moh 2:602e9bb053a0 609 invun_cool=0;
el14moh 2:602e9bb053a0 610 }
el14moh 2:602e9bb053a0 611 }
el14moh 2:602e9bb053a0 612 }
el14moh 2:602e9bb053a0 613
el14moh 2:602e9bb053a0 614 void checkWallCollision() // checks for any collisions (i.e. player has hit a wall or side of the screen)
el14moh 2:602e9bb053a0 615 {
el14moh 9:ca800196baeb 616 if (mortal) {
el14moh 0:6b29f9c29a2a 617
el14moh 9:ca800196baeb 618 // LEFT WALL
el14moh 9:ca800196baeb 619 if ((((i - PLAYERRADIUS) <= leftwall.x) && (leftwall.x <= (i + PLAYERRADIUS))) && (j > (leftwall.y+3) || j < (leftwall.y-3))) {
el14moh 9:ca800196baeb 620 game_over_flag = 1;
el14moh 9:ca800196baeb 621 }
el14moh 0:6b29f9c29a2a 622
el14moh 9:ca800196baeb 623 // RIGHT WALL
el14moh 9:ca800196baeb 624 if ((((i - PLAYERRADIUS) <= rightwall.x) && (rightwall.x <= (i + PLAYERRADIUS))) && (j > (rightwall.y+3) || j < (rightwall.y-3))) {
el14moh 9:ca800196baeb 625 game_over_flag = 1;
el14moh 9:ca800196baeb 626 }
el14moh 0:6b29f9c29a2a 627
el14moh 9:ca800196baeb 628 // DOWN WALL
el14moh 9:ca800196baeb 629 if ((((j - PLAYERRADIUS) <= downwall.y) && (downwall.y <= (j - PLAYERRADIUS))) && (i > (downwall.x+9) || i < (downwall.x-9))) { // if player x is 4 or more than wall x, it has missed the gap
el14moh 9:ca800196baeb 630 game_over_flag = 1;
el14moh 9:ca800196baeb 631 }
el14moh 0:6b29f9c29a2a 632
el14moh 9:ca800196baeb 633 // UP WALL
el14moh 9:ca800196baeb 634 if (((j + PLAYERRADIUS) == upwall.y || (j - PLAYERRADIUS) == upwall.y) && (i > (upwall.x+9) || i < (upwall.x-9))) { // if player x is 4 or more than wall x, it has missed the gap
el14moh 9:ca800196baeb 635 game_over_flag = 1;
el14moh 9:ca800196baeb 636 }
el14moh 0:6b29f9c29a2a 637 }
el14moh 0:6b29f9c29a2a 638 }
el14moh 0:6b29f9c29a2a 639
el14moh 0:6b29f9c29a2a 640 void updateScreen() // refreshes the screen, redraws player and walls
el14moh 0:6b29f9c29a2a 641 {
el14moh 0:6b29f9c29a2a 642 lcd.clear();
el14moh 2:602e9bb053a0 643 if (mortal) {
el14moh 2:602e9bb053a0 644 lcd.drawCircle(i,j,PLAYERRADIUS,1);
el14moh 2:602e9bb053a0 645 } else {
el14moh 2:602e9bb053a0 646 if (counter % 2 == 0) {
el14moh 2:602e9bb053a0 647 lcd.drawCircle(i,j,PLAYERRADIUS,1);
el14moh 2:602e9bb053a0 648 }
el14moh 2:602e9bb053a0 649 }
el14moh 0:6b29f9c29a2a 650 lcd.refresh(); // update display
el14moh 0:6b29f9c29a2a 651
el14moh 3:8890b4605a10 652 if (saves > 0) {
el14moh 3:8890b4605a10 653 lcd.drawCircle(2,7,1,1);
el14moh 3:8890b4605a10 654 }
el14moh 3:8890b4605a10 655 if (saves > 1) {
el14moh 3:8890b4605a10 656 lcd.drawCircle(2,15,1,1);
el14moh 3:8890b4605a10 657 }
el14moh 3:8890b4605a10 658 if (saves > 2) {
el14moh 3:8890b4605a10 659 lcd.drawCircle(2,23,1,1);
el14moh 3:8890b4605a10 660 }
el14moh 3:8890b4605a10 661 if (saves > 3) {
el14moh 3:8890b4605a10 662 lcd.drawCircle(2,31,1,1);
el14moh 3:8890b4605a10 663 }
el14moh 3:8890b4605a10 664 if (saves > 4) {
el14moh 3:8890b4605a10 665 lcd.drawCircle(2,39,1,1);
el14moh 3:8890b4605a10 666 }
el14moh 3:8890b4605a10 667
el14moh 2:602e9bb053a0 668
el14moh 0:6b29f9c29a2a 669 // draw Border
el14moh 6:153680563027 670 draw_border();
el14moh 0:6b29f9c29a2a 671
el14moh 0:6b29f9c29a2a 672 // draw walls
el14moh 0:6b29f9c29a2a 673 // LEFT WALL
el14moh 0:6b29f9c29a2a 674 lcd.drawLine(leftwall.x,leftwall.y+5,leftwall.x,44,1);
el14moh 0:6b29f9c29a2a 675 lcd.drawLine(leftwall.x,leftwall.y-5,leftwall.x,3,1);
el14moh 0:6b29f9c29a2a 676 lcd.drawLine(leftwall.x+1,leftwall.y+5,leftwall.x+1,44,1);
el14moh 0:6b29f9c29a2a 677 lcd.drawLine(leftwall.x+1,leftwall.y-5,leftwall.x+1,3,1);
el14moh 0:6b29f9c29a2a 678
el14moh 0:6b29f9c29a2a 679 // RIGHT WALL
el14moh 0:6b29f9c29a2a 680 if (counter > 200) {
el14moh 0:6b29f9c29a2a 681 lcd.drawLine(rightwall.x,rightwall.y+5,rightwall.x,44,1);
el14moh 0:6b29f9c29a2a 682 lcd.drawLine(rightwall.x,rightwall.y-5,rightwall.x,3,1);
el14moh 0:6b29f9c29a2a 683 lcd.drawLine(rightwall.x-1,rightwall.y+5,rightwall.x-1,44,1);
el14moh 0:6b29f9c29a2a 684 lcd.drawLine(rightwall.x-1,rightwall.y-5,rightwall.x-1,3,1);
el14moh 0:6b29f9c29a2a 685 }
el14moh 0:6b29f9c29a2a 686
el14moh 0:6b29f9c29a2a 687 // DOWN WALL
el14moh 0:6b29f9c29a2a 688 if (counter > 600) {
el14moh 0:6b29f9c29a2a 689 lcd.drawLine(downwall.x+11,downwall.y,80,downwall.y,1);
el14moh 3:8890b4605a10 690 lcd.drawLine(downwall.x-11,downwall.y,8,downwall.y,1);
el14moh 0:6b29f9c29a2a 691 lcd.drawLine(downwall.x+11,downwall.y-1,80,downwall.y-1,1);
el14moh 3:8890b4605a10 692 lcd.drawLine(downwall.x-11,downwall.y-1,8,downwall.y-1,1);
el14moh 0:6b29f9c29a2a 693 }
el14moh 0:6b29f9c29a2a 694
el14moh 0:6b29f9c29a2a 695 // UP WALL
el14moh 0:6b29f9c29a2a 696 if (counter > 1500) {
el14moh 0:6b29f9c29a2a 697 lcd.drawLine(upwall.x+11,upwall.y,80,upwall.y,1);
el14moh 3:8890b4605a10 698 lcd.drawLine(upwall.x-11,upwall.y,8,upwall.y,1);
el14moh 0:6b29f9c29a2a 699 lcd.drawLine(upwall.x+11,upwall.y+1,80,upwall.y+1,1);
el14moh 3:8890b4605a10 700 lcd.drawLine(upwall.x-11,upwall.y+1,8,upwall.y+1,1);
el14moh 0:6b29f9c29a2a 701 }
el14moh 0:6b29f9c29a2a 702
el14moh 0:6b29f9c29a2a 703 lcd.refresh();
el14moh 0:6b29f9c29a2a 704 }
el14moh 0:6b29f9c29a2a 705
el14moh 0:6b29f9c29a2a 706 void warning ()
el14moh 0:6b29f9c29a2a 707 {
el14moh 0:6b29f9c29a2a 708 if (counter == 170) {
el14moh 0:6b29f9c29a2a 709 lcd.inverseMode();
el14moh 0:6b29f9c29a2a 710 } else if (counter == 570) {
el14moh 0:6b29f9c29a2a 711 lcd.inverseMode();
el14moh 0:6b29f9c29a2a 712 } else if (counter == 1470) {
el14moh 0:6b29f9c29a2a 713 lcd.inverseMode();
el14moh 0:6b29f9c29a2a 714 } else {
el14moh 0:6b29f9c29a2a 715 lcd.normalMode();
el14moh 0:6b29f9c29a2a 716 }
el14moh 0:6b29f9c29a2a 717 }
el14moh 0:6b29f9c29a2a 718
el14moh 0:6b29f9c29a2a 719 void game_timer_isr() // sets flag for timer interrupt
el14moh 0:6b29f9c29a2a 720 {
el14moh 0:6b29f9c29a2a 721 g_timer_flag = 1;
el14moh 0:6b29f9c29a2a 722 }
el14moh 0:6b29f9c29a2a 723
el14moh 2:602e9bb053a0 724 void button_isr()
el14moh 2:602e9bb053a0 725 {
el14moh 2:602e9bb053a0 726 g_button_flag = 1;
el14moh 2:602e9bb053a0 727 }
el14moh 2:602e9bb053a0 728
el14moh 0:6b29f9c29a2a 729 void initDisplay() // initialises the LCD display
el14moh 0:6b29f9c29a2a 730 {
el14moh 0:6b29f9c29a2a 731 lcd.init();
el14moh 0:6b29f9c29a2a 732 lcd.normalMode();
el14moh 0:6b29f9c29a2a 733 lcd.setBrightness(1.0F-backlight); // brightness pot on PCB is soldered in the wrong direction, (1.0F-backlight) inverts the reading
el14moh 0:6b29f9c29a2a 734 }
el14moh 0:6b29f9c29a2a 735
el14moh 0:6b29f9c29a2a 736 void calibrateJoystick() // read default positions of the joystick to calibrate later readings
el14moh 0:6b29f9c29a2a 737 {
el14moh 0:6b29f9c29a2a 738 button.mode(PullDown);
el14moh 0:6b29f9c29a2a 739 // must not move during calibration
el14moh 0:6b29f9c29a2a 740 joystick.x0 = xPot; // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly)
el14moh 0:6b29f9c29a2a 741 joystick.y0 = yPot;
el14moh 0:6b29f9c29a2a 742 }
el14moh 0:6b29f9c29a2a 743 void updateJoystick() // reads direction the joystick has been moved
el14moh 0:6b29f9c29a2a 744 {
el14moh 0:6b29f9c29a2a 745 // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
el14moh 0:6b29f9c29a2a 746 joystick.x = xPot - joystick.x0;
el14moh 0:6b29f9c29a2a 747 joystick.y = yPot - joystick.y0;
el14moh 0:6b29f9c29a2a 748 // read button state
el14moh 0:6b29f9c29a2a 749 joystick.button = button;
el14moh 0:6b29f9c29a2a 750
el14moh 0:6b29f9c29a2a 751 // calculate direction depending on x,y values
el14moh 0:6b29f9c29a2a 752 // tolerance allows a little lee-way in case joystick not exactly in the stated direction
el14moh 0:6b29f9c29a2a 753 if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
el14moh 0:6b29f9c29a2a 754 joystick.direction = CENTRE;
el14moh 0:6b29f9c29a2a 755 } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
el14moh 0:6b29f9c29a2a 756 joystick.direction = UP;
el14moh 0:6b29f9c29a2a 757 } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
el14moh 0:6b29f9c29a2a 758 joystick.direction = DOWN;
el14moh 0:6b29f9c29a2a 759 } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
el14moh 0:6b29f9c29a2a 760 joystick.direction = LEFT;
el14moh 0:6b29f9c29a2a 761 } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
el14moh 0:6b29f9c29a2a 762 joystick.direction = RIGHT;
el14moh 0:6b29f9c29a2a 763 } else if ( joystick.y > DIRECTION_TOLERANCE && joystick.x > DIRECTION_TOLERANCE) {
el14moh 0:6b29f9c29a2a 764 joystick.direction = UPLEFT;
el14moh 0:6b29f9c29a2a 765 } else if ( joystick.y > DIRECTION_TOLERANCE && joystick.x < DIRECTION_TOLERANCE) {
el14moh 0:6b29f9c29a2a 766 joystick.direction = UPRIGHT;
el14moh 0:6b29f9c29a2a 767 } else if ( joystick.x > DIRECTION_TOLERANCE && joystick.y < DIRECTION_TOLERANCE) {
el14moh 0:6b29f9c29a2a 768 joystick.direction = DOWNLEFT;
el14moh 0:6b29f9c29a2a 769 } else if ( joystick.x < DIRECTION_TOLERANCE && joystick.y < DIRECTION_TOLERANCE) {
el14moh 0:6b29f9c29a2a 770 joystick.direction = DOWNRIGHT;
el14moh 0:6b29f9c29a2a 771 }
el14moh 0:6b29f9c29a2a 772
el14moh 0:6b29f9c29a2a 773 else {
el14moh 0:6b29f9c29a2a 774 joystick.direction = UNKNOWN;
el14moh 0:6b29f9c29a2a 775 }
el14moh 0:6b29f9c29a2a 776
el14moh 0:6b29f9c29a2a 777
el14moh 0:6b29f9c29a2a 778 printFlag = 1; // set flag for printing
el14moh 0:6b29f9c29a2a 779 }
el14moh 0:6b29f9c29a2a 780
el14moh 0:6b29f9c29a2a 781 void debug() // prints for debug purposes
el14moh 0:6b29f9c29a2a 782 {
el14moh 0:6b29f9c29a2a 783 if (printFlag) { // if flag set, clear flag and print joystick values to serial port
el14moh 0:6b29f9c29a2a 784 printFlag = 0;
el14moh 2:602e9bb053a0 785 serial.printf("saves = %d \n",saves);
el14moh 0:6b29f9c29a2a 786 }
el14moh 0:6b29f9c29a2a 787 }
el14moh 0:6b29f9c29a2a 788
el14moh 7:ca18e8775d8d 789 void initSerial() // sets baud rate for serial
el14moh 0:6b29f9c29a2a 790 {
el14moh 0:6b29f9c29a2a 791 serial.baud(115200);
el14moh 0:6b29f9c29a2a 792 }
el14moh 7:ca18e8775d8d 793 void initGame()
el14moh 3:8890b4605a10 794 {
el14moh 0:6b29f9c29a2a 795
el14moh 3:8890b4605a10 796 g_button_flag = 0;
el14moh 3:8890b4605a10 797 leftwall.y = rand() % 27+8;
el14moh 3:8890b4605a10 798 leftwall.x = 0;
el14moh 9:ca800196baeb 799 rightwall.y = rand() % 27+8;
el14moh 6:153680563027 800 rightwall.x = 6;
el14moh 9:ca800196baeb 801 downwall.x = rand() % 58+13;
el14moh 3:8890b4605a10 802 downwall.y = 0;
el14moh 9:ca800196baeb 803 upwall.x = rand() % 58+13;
el14moh 3:8890b4605a10 804 upwall.y = 0;
el14moh 3:8890b4605a10 805 rightwall.cooldown = 61;
el14moh 3:8890b4605a10 806 counter = 0;
el14moh 7:ca18e8775d8d 807 score = 0;
el14moh 3:8890b4605a10 808
el14moh 3:8890b4605a10 809 saves = 5;
el14moh 3:8890b4605a10 810
el14moh 3:8890b4605a10 811 i = 42;
el14moh 3:8890b4605a10 812 j = 24;
el14moh 3:8890b4605a10 813
el14moh 3:8890b4605a10 814 }
el14moh 6:153680563027 815
el14moh 8:b49e0cc362f2 816 void blink() // command for brief flash
el14moh 6:153680563027 817 {
el14moh 6:153680563027 818 lcd.inverseMode();
el14moh 6:153680563027 819 wait(0.2);
el14moh 6:153680563027 820 lcd.normalMode();
el14moh 6:153680563027 821 }
el14moh 6:153680563027 822
el14moh 6:153680563027 823 void printHelp()
el14moh 6:153680563027 824 {
el14moh 9:ca800196baeb 825 while (1) {
el14moh 9:ca800196baeb 826 lcd.printString("Try and",0,1);
el14moh 9:ca800196baeb 827 lcd.printString("survive for",0,2);
el14moh 9:ca800196baeb 828 lcd.printString("as long as ",0,3);
el14moh 9:ca800196baeb 829 lcd.printString("possible!",0,4);
el14moh 9:ca800196baeb 830 lcd.refresh();
el14moh 9:ca800196baeb 831 if (g_button_flag) {
el14moh 9:ca800196baeb 832 //g_button_flag = 0;
el14moh 9:ca800196baeb 833 playNote(NOTE_E2,0.1);
el14moh 9:ca800196baeb 834 blink();
el14moh 9:ca800196baeb 835 lcd.clear();
el14moh 9:ca800196baeb 836 break;
el14moh 9:ca800196baeb 837 }
el14moh 9:ca800196baeb 838 }
el14moh 9:ca800196baeb 839 g_button_flag = 0;
el14moh 9:ca800196baeb 840 while(1) {
el14moh 9:ca800196baeb 841 lcd.printString("Get through",0,1);
el14moh 9:ca800196baeb 842 lcd.printString("the holes in",0,2);
el14moh 9:ca800196baeb 843 lcd.printString("the walls with",0,3);
el14moh 9:ca800196baeb 844 lcd.printString("the joystick",0,4);
el14moh 9:ca800196baeb 845 lcd.refresh();
el14moh 9:ca800196baeb 846 if (g_button_flag) {
el14moh 9:ca800196baeb 847 //g_button_flag = 0;
el14moh 9:ca800196baeb 848 playNote(NOTE_E2,0.1);
el14moh 9:ca800196baeb 849 blink();
el14moh 9:ca800196baeb 850 lcd.clear();
el14moh 9:ca800196baeb 851 break;
el14moh 9:ca800196baeb 852 }
el14moh 9:ca800196baeb 853 }
el14moh 9:ca800196baeb 854 g_button_flag = 0;
el14moh 9:ca800196baeb 855 while(1) {
el14moh 9:ca800196baeb 856 lcd.printString("Press the",0,1);
el14moh 9:ca800196baeb 857 lcd.printString("stick to",0,2);
el14moh 9:ca800196baeb 858 lcd.printString("be briefly",0,3);
el14moh 9:ca800196baeb 859 lcd.printString("untouchable",0,4);
el14moh 9:ca800196baeb 860 lcd.refresh();
el14moh 9:ca800196baeb 861 if (g_button_flag) {
el14moh 9:ca800196baeb 862 // g_button_flag = 0;
el14moh 9:ca800196baeb 863 playNote(NOTE_E2,0.1);
el14moh 9:ca800196baeb 864 blink();
el14moh 9:ca800196baeb 865 lcd.clear();
el14moh 9:ca800196baeb 866 break;
el14moh 9:ca800196baeb 867 }
el14moh 9:ca800196baeb 868 }
el14moh 9:ca800196baeb 869 g_button_flag = 0;
el14moh 9:ca800196baeb 870 while(1) {
el14moh 9:ca800196baeb 871 lcd.printString("But don't use",0,1);
el14moh 9:ca800196baeb 872 lcd.printString("it too much!",0,2);
el14moh 9:ca800196baeb 873 lcd.printString("you can only",0,3);
el14moh 9:ca800196baeb 874 lcd.printString("do it 5 times",0,4);
el14moh 9:ca800196baeb 875 lcd.refresh();
el14moh 9:ca800196baeb 876 if (g_button_flag) {
el14moh 9:ca800196baeb 877 // g_button_flag = 0;
el14moh 9:ca800196baeb 878 playNote(NOTE_E2,0.1);
el14moh 9:ca800196baeb 879 blink();
el14moh 9:ca800196baeb 880 lcd.clear();
el14moh 9:ca800196baeb 881 break;
el14moh 9:ca800196baeb 882 }
el14moh 9:ca800196baeb 883 }
el14moh 9:ca800196baeb 884 g_button_flag = 0;
el14moh 9:ca800196baeb 885 while(1) {
el14moh 9:ca800196baeb 886 lcd.printString("Lastly, keep",0,1);
el14moh 9:ca800196baeb 887 lcd.printString("an eye on the",0,2);
el14moh 9:ca800196baeb 888 lcd.printString("borders of",0,3);
el14moh 9:ca800196baeb 889 lcd.printString("the screen...",0,4);
el14moh 9:ca800196baeb 890 lcd.refresh();
el14moh 9:ca800196baeb 891 if (g_button_flag) {
el14moh 9:ca800196baeb 892 // g_button_flag = 0;
el14moh 9:ca800196baeb 893 playNote(NOTE_E2,0.1);
el14moh 9:ca800196baeb 894 blink();
el14moh 9:ca800196baeb 895 lcd.clear();
el14moh 9:ca800196baeb 896 break;
el14moh 9:ca800196baeb 897 }
el14moh 9:ca800196baeb 898 }
el14moh 9:ca800196baeb 899 g_button_flag = 0;
el14moh 9:ca800196baeb 900 while(1) {
el14moh 9:ca800196baeb 901 lcd.printString("See where the",0,1);
el14moh 9:ca800196baeb 902 lcd.printString("holes are",0,2);
el14moh 9:ca800196baeb 903 lcd.printString("before the",0,3);
el14moh 9:ca800196baeb 904 lcd.printString("walls move!",0,4);
el14moh 9:ca800196baeb 905 lcd.refresh();
el14moh 9:ca800196baeb 906 if (g_button_flag) {
el14moh 9:ca800196baeb 907 g_button_flag = 0;
el14moh 9:ca800196baeb 908 playNote(NOTE_E2,0.1);
el14moh 9:ca800196baeb 909 blink();
el14moh 9:ca800196baeb 910 lcd.clear();
el14moh 9:ca800196baeb 911 break;
el14moh 9:ca800196baeb 912 }
el14moh 9:ca800196baeb 913 }
el14moh 6:153680563027 914 }
el14moh 6:153680563027 915
el14moh 6:153680563027 916 void printScores()
el14moh 6:153680563027 917 {
el14moh 9:ca800196baeb 918 while(1) {
el14moh 9:ca800196baeb 919 lcd.printString("Highscores",13,0);
el14moh 9:ca800196baeb 920 lcd.printString("1st:",6,2);
el14moh 9:ca800196baeb 921 lcd.printString("2nd:",6,3);
el14moh 9:ca800196baeb 922 lcd.printString("3rd:",6,4);
el14moh 9:ca800196baeb 923 char first[14];
el14moh 9:ca800196baeb 924 char second[14];
el14moh 9:ca800196baeb 925 char third[14];
el14moh 9:ca800196baeb 926 int one = sprintf(first,"%d",hiscore.one);
el14moh 9:ca800196baeb 927 int two = sprintf(second,"%d",hiscore.two);
el14moh 9:ca800196baeb 928 int three = sprintf(third,"%d",hiscore.three);
el14moh 8:b49e0cc362f2 929
el14moh 9:ca800196baeb 930 lcd.printString(first,30,2);
el14moh 9:ca800196baeb 931 lcd.printString(second,30,3);
el14moh 9:ca800196baeb 932 lcd.printString(third,30,4);
el14moh 8:b49e0cc362f2 933
el14moh 9:ca800196baeb 934 lcd.refresh();
el14moh 8:b49e0cc362f2 935
el14moh 9:ca800196baeb 936 if (g_button_flag) {
el14moh 9:ca800196baeb 937 g_button_flag = 0;
el14moh 9:ca800196baeb 938 playNote(NOTE_E2,0.1);
el14moh 9:ca800196baeb 939 blink();
el14moh 9:ca800196baeb 940 lcd.clear();
el14moh 9:ca800196baeb 941 break;
el14moh 9:ca800196baeb 942 }
el14moh 9:ca800196baeb 943 }
el14moh 6:153680563027 944 }
el14moh 6:153680563027 945
el14moh 8:b49e0cc362f2 946 void draw_border() // draws game border
el14moh 6:153680563027 947 {
el14moh 6:153680563027 948 lcd.drawLine(7,2,81,2,1);
el14moh 6:153680563027 949 lcd.drawLine(7,2,7,45,1);
el14moh 6:153680563027 950 lcd.drawLine(81,2,81,45,1);
el14moh 6:153680563027 951 lcd.drawLine(7,45,81,45,1);
el14moh 6:153680563027 952
el14moh 6:153680563027 953 lcd.drawLine(5,0,83,0,1);
el14moh 6:153680563027 954 lcd.drawLine(5,0,5,47,1);
el14moh 6:153680563027 955 lcd.drawLine(83,0,83,47,1);
el14moh 6:153680563027 956 lcd.drawLine(5,47,83,47,1);
el14moh 6:153680563027 957
el14moh 6:153680563027 958 lcd.refresh();
el14moh 6:153680563027 959 }
el14moh 6:153680563027 960
el14moh 6:153680563027 961 void calculateHighscores()
el14moh 6:153680563027 962 {
el14moh 7:ca18e8775d8d 963 if (score > hiscore.one) {
el14moh 6:153680563027 964 hiscore.three = hiscore.two;
el14moh 6:153680563027 965 hiscore.two = hiscore.one;
el14moh 7:ca18e8775d8d 966 hiscore.one = score;
el14moh 7:ca18e8775d8d 967 } else if ((hiscore.one > score)&&(score > hiscore.two)) {
el14moh 6:153680563027 968 hiscore.three = hiscore.two;
el14moh 7:ca18e8775d8d 969 hiscore.two = score;
el14moh 7:ca18e8775d8d 970 } else if ((hiscore.two > score)&&(score > hiscore.three)) {
el14moh 7:ca18e8775d8d 971 hiscore.three = score;
el14moh 6:153680563027 972 }
el14moh 6:153680563027 973 }
el14moh 6:153680563027 974
el14moh 6:153680563027 975 void initHiscores()
el14moh 6:153680563027 976 {
el14moh 6:153680563027 977 hiscore.one = 0;
el14moh 6:153680563027 978 hiscore.two = 0;
el14moh 6:153680563027 979 hiscore.three = 0;
el14moh 8:b49e0cc362f2 980 }
el14moh 8:b49e0cc362f2 981
el14moh 8:b49e0cc362f2 982 void playNote(int freq, float time)
el14moh 8:b49e0cc362f2 983 {
el14moh 8:b49e0cc362f2 984 if(!MUTE) { // no sound if MUTE
el14moh 8:b49e0cc362f2 985 buzzer.period(1.0/freq); // 1 KHz
el14moh 8:b49e0cc362f2 986 buzzer.write(0.0);
el14moh 8:b49e0cc362f2 987 buzzer.write(0.5);
el14moh 8:b49e0cc362f2 988 wait(time);
el14moh 8:b49e0cc362f2 989 buzzer.write(0.0);
el14moh 8:b49e0cc362f2 990 } else {
el14moh 8:b49e0cc362f2 991 wait(time); // wait included so that function still takes the same time to execute
el14moh 8:b49e0cc362f2 992 }
el14moh 6:153680563027 993 }