My ELEC2645 joystick project Tetris Game NAME: JIANWEI CHEN SID: 200879849

Dependencies:   N5110 SDFileSystem mbed

Committer:
cjw851102
Date:
Thu May 05 09:18:01 2016 +0000
Revision:
4:463abe5f5135
Final version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cjw851102 4:463abe5f5135 1 /**
cjw851102 4:463abe5f5135 2 @file Game.h
cjw851102 4:463abe5f5135 3 @brief Header file containing functions prototypes, defines and global variables for the tetris game.
cjw851102 4:463abe5f5135 4 @brief Revision 1.0.
cjw851102 4:463abe5f5135 5 @author JIANWEI CHEN
cjw851102 4:463abe5f5135 6 @date May 2016
cjw851102 4:463abe5f5135 7 */
cjw851102 4:463abe5f5135 8
cjw851102 4:463abe5f5135 9 #ifndef GAME_H
cjw851102 4:463abe5f5135 10 #define GAME_H
cjw851102 4:463abe5f5135 11
cjw851102 4:463abe5f5135 12 #include "mbed.h"
cjw851102 4:463abe5f5135 13 #include "Patterns.h"
cjw851102 4:463abe5f5135 14 #include "N5110.h"
cjw851102 4:463abe5f5135 15 #include "SDFileSystem.h"
cjw851102 4:463abe5f5135 16 #include "main.h"
cjw851102 4:463abe5f5135 17
cjw851102 4:463abe5f5135 18 //! Create patterns object
cjw851102 4:463abe5f5135 19 Patterns patterns;
cjw851102 4:463abe5f5135 20 /**
cjw851102 4:463abe5f5135 21 Create ticker object for game
cjw851102 4:463abe5f5135 22 @brief ticker to control the speed of game
cjw851102 4:463abe5f5135 23 */
cjw851102 4:463abe5f5135 24 Ticker game;
cjw851102 4:463abe5f5135 25
cjw851102 4:463abe5f5135 26 ////////////////////////////////////////////////////////
cjw851102 4:463abe5f5135 27 // Variables
cjw851102 4:463abe5f5135 28 ////////////////////////////////////////////////////////
cjw851102 4:463abe5f5135 29
cjw851102 4:463abe5f5135 30 int xOld; /*!< Variable for storing the pattern previous position when game is runnung */
cjw851102 4:463abe5f5135 31 int typeCount = 0; /*!< Variable for counting elements in array typeArray[100]*/
cjw851102 4:463abe5f5135 32 int nextTypeCount; /*!< Variable to show the position of next element in typeArray[100] i.e. nextTypeCount=typeCount+1*/
cjw851102 4:463abe5f5135 33
cjw851102 4:463abe5f5135 34 /** Flag to show left hand side conllision of pattern
cjw851102 4:463abe5f5135 35 @note flag = 0 - there is no collision on the left
cjw851102 4:463abe5f5135 36 @note flag = 1 - there is collision on the left
cjw851102 4:463abe5f5135 37 */
cjw851102 4:463abe5f5135 38 int left_collision_flag = 0;
cjw851102 4:463abe5f5135 39
cjw851102 4:463abe5f5135 40 /** Flag to show right hand side conllision of pattern
cjw851102 4:463abe5f5135 41 @note flag = 0 - there is no collision
cjw851102 4:463abe5f5135 42 @note flag = 1 - there is collision
cjw851102 4:463abe5f5135 43 */
cjw851102 4:463abe5f5135 44 int right_collision_flag = 0;
cjw851102 4:463abe5f5135 45
cjw851102 4:463abe5f5135 46 /** Flag to show bottom conllision of pattern
cjw851102 4:463abe5f5135 47 @note flag = 0 - there is no collision
cjw851102 4:463abe5f5135 48 @note flag = 1 - there is collision
cjw851102 4:463abe5f5135 49 */
cjw851102 4:463abe5f5135 50 int bottom_collision_flag = 0;
cjw851102 4:463abe5f5135 51
cjw851102 4:463abe5f5135 52 /** Flag to show top conllision of pattern
cjw851102 4:463abe5f5135 53 @note flag = 0 - there is no collision
cjw851102 4:463abe5f5135 54 @note flag = 1 - there is collision
cjw851102 4:463abe5f5135 55 */
cjw851102 4:463abe5f5135 56 int top_collision_flag = 0;
cjw851102 4:463abe5f5135 57
cjw851102 4:463abe5f5135 58 /** Flag to show if there is pixels set on the 4 pixels distance away from the bottom of pattern
cjw851102 4:463abe5f5135 59 @brief if flag = 0, user can pull joystick down to make pattern falling faster
cjw851102 4:463abe5f5135 60 @note flag = 0 - there is no collision
cjw851102 4:463abe5f5135 61 @note flag = 1 - there is collision
cjw851102 4:463abe5f5135 62 */
cjw851102 4:463abe5f5135 63 int fastmove_bottom_collision_flag = 0;
cjw851102 4:463abe5f5135 64
cjw851102 4:463abe5f5135 65 /** Flag to show if allow patterns to rotate
cjw851102 4:463abe5f5135 66 @note flag = 0 - allow
cjw851102 4:463abe5f5135 67 @note flag = 1 - not allow
cjw851102 4:463abe5f5135 68 */
cjw851102 4:463abe5f5135 69 int rotation_collision_flag = 0;
cjw851102 4:463abe5f5135 70
cjw851102 4:463abe5f5135 71 /** Two dimension array to store current pattern pixels setting in a 6x6 square
cjw851102 4:463abe5f5135 72 @note For example, if current pattern is "L"
cjw851102 4:463abe5f5135 73 @note the pixels setting is
cjw851102 4:463abe5f5135 74 @note 1 1 0 0 0 0
cjw851102 4:463abe5f5135 75 @note 1 1 0 0 0 0
cjw851102 4:463abe5f5135 76 @note 1 1 0 0 0 0
cjw851102 4:463abe5f5135 77 @note 1 1 0 0 0 0
cjw851102 4:463abe5f5135 78 @note 1 1 1 1 0 0
cjw851102 4:463abe5f5135 79 @note 1 1 1 1 0 0
cjw851102 4:463abe5f5135 80 */
cjw851102 4:463abe5f5135 81 int pattern_buffer[6][6];
cjw851102 4:463abe5f5135 82
cjw851102 4:463abe5f5135 83 /** Array to store types of pattern
cjw851102 4:463abe5f5135 84 @brief 100 random integers in the range of 0~6
cjw851102 4:463abe5f5135 85 @brief will be stored in the array in order to generate
cjw851102 4:463abe5f5135 86 @brief random type of pattern each time new pattern is generated
cjw851102 4:463abe5f5135 87 */
cjw851102 4:463abe5f5135 88 int typeArray[100];
cjw851102 4:463abe5f5135 89 int buffer[84][48]; /*!< Array to store whole screen pixel settings */
cjw851102 4:463abe5f5135 90 int score=0; /*!< Variable to store score in the game */
cjw851102 4:463abe5f5135 91 volatile int g_game_flag = 0; /*!< Flag for game ticker */
cjw851102 4:463abe5f5135 92
cjw851102 4:463abe5f5135 93 /** Struct for position
cjw851102 4:463abe5f5135 94 @brief Contains the pattern position(x,y),
cjw851102 4:463abe5f5135 95 @brief pattern type and rotation
cjw851102 4:463abe5f5135 96 */
cjw851102 4:463abe5f5135 97 struct Position {
cjw851102 4:463abe5f5135 98 float x;
cjw851102 4:463abe5f5135 99 float y;
cjw851102 4:463abe5f5135 100 int type;
cjw851102 4:463abe5f5135 101 int rotation;
cjw851102 4:463abe5f5135 102 };
cjw851102 4:463abe5f5135 103 typedef struct Position position;
cjw851102 4:463abe5f5135 104 position pos;
cjw851102 4:463abe5f5135 105
cjw851102 4:463abe5f5135 106 ////////////////////////////////////////////////////////////////////////
cjw851102 4:463abe5f5135 107 // Functions
cjw851102 4:463abe5f5135 108 ////////////////////////////////////////////////////////////////////////
cjw851102 4:463abe5f5135 109 /**
cjw851102 4:463abe5f5135 110 Game ticker isr function
cjw851102 4:463abe5f5135 111 */
cjw851102 4:463abe5f5135 112 void game_isr();
cjw851102 4:463abe5f5135 113
cjw851102 4:463abe5f5135 114 /**
cjw851102 4:463abe5f5135 115 Initialise the variables in game
cjw851102 4:463abe5f5135 116 */
cjw851102 4:463abe5f5135 117 void init_game();
cjw851102 4:463abe5f5135 118
cjw851102 4:463abe5f5135 119 /** Drawing the pattern at position (x,y)
cjw851102 4:463abe5f5135 120 @param type - type of pattern (0~6)
cjw851102 4:463abe5f5135 121 @param rotation - rotation of pattern (0~3)
cjw851102 4:463abe5f5135 122 @param x - x co-ordinate of pattern, which is the top left corner pixel of 6x6 square
cjw851102 4:463abe5f5135 123 @param y - y co-ordinate of pattern, which is the top left corner pixel of 6x6 square
cjw851102 4:463abe5f5135 124 @param fill - fill = 0 white, fill = 1 black
cjw851102 4:463abe5f5135 125 */
cjw851102 4:463abe5f5135 126 void drawPattern(int type,int rotation,int x,int y,int fill);
cjw851102 4:463abe5f5135 127
cjw851102 4:463abe5f5135 128 /**Left collision detect
cjw851102 4:463abe5f5135 129 @brief Function to check the left collision of current falling pattern and set the left_collision_flag
cjw851102 4:463abe5f5135 130 */
cjw851102 4:463abe5f5135 131 void left_collisionDetect();
cjw851102 4:463abe5f5135 132
cjw851102 4:463abe5f5135 133 /**Right collision detect
cjw851102 4:463abe5f5135 134 @brief Function to check the right collision of current falling pattern and set the left_collision_flag
cjw851102 4:463abe5f5135 135 */
cjw851102 4:463abe5f5135 136 void right_collisionDetect();
cjw851102 4:463abe5f5135 137
cjw851102 4:463abe5f5135 138 /**Bottom collision detect
cjw851102 4:463abe5f5135 139 @brief Function to check the bottom collision of current falling pattern and set the right_collision_flag
cjw851102 4:463abe5f5135 140 */
cjw851102 4:463abe5f5135 141 void bottom_collisionDetect();
cjw851102 4:463abe5f5135 142
cjw851102 4:463abe5f5135 143 /**top collision detect
cjw851102 4:463abe5f5135 144 @brief Function to check the top collision of current falling pattern and set the top_collision_flag
cjw851102 4:463abe5f5135 145 */
cjw851102 4:463abe5f5135 146 void top_collisionDetect();
cjw851102 4:463abe5f5135 147
cjw851102 4:463abe5f5135 148 /**Rotation collision detect
cjw851102 4:463abe5f5135 149 @brief Function to check if the program should allow user to rotate the pattern and set the rotation_collision_flag
cjw851102 4:463abe5f5135 150 */
cjw851102 4:463abe5f5135 151 void rotation_collisionDetect();
cjw851102 4:463abe5f5135 152
cjw851102 4:463abe5f5135 153 /**Fast move collision detect
cjw851102 4:463abe5f5135 154 @brief Function to check if the program should allow user to move the pattern falling faster and set the fastmove_collision_flag
cjw851102 4:463abe5f5135 155 @note check the 4 pixels distance away from the bottom of pattern
cjw851102 4:463abe5f5135 156 */
cjw851102 4:463abe5f5135 157 void fastmove_bottom_collisionDetect();
cjw851102 4:463abe5f5135 158
cjw851102 4:463abe5f5135 159 /**Get pattern pixel settings
cjw851102 4:463abe5f5135 160 @brief Function to get the current falling pattern pixel settings
cjw851102 4:463abe5f5135 161 @note pixels setting will be store in pattern_buffer[6][6];
cjw851102 4:463abe5f5135 162 @param type - type of pattern (0~6)
cjw851102 4:463abe5f5135 163 @param rotation - rotation of pattern (0~3)
cjw851102 4:463abe5f5135 164 */
cjw851102 4:463abe5f5135 165 void get_pattern(int type, int rotatin);
cjw851102 4:463abe5f5135 166
cjw851102 4:463abe5f5135 167 /**Scan the whole screen pixel settings
cjw851102 4:463abe5f5135 168 @brief Function to store the whole screen pixel settings and store in buffer[84][48]
cjw851102 4:463abe5f5135 169 */
cjw851102 4:463abe5f5135 170 void scan();
cjw851102 4:463abe5f5135 171
cjw851102 4:463abe5f5135 172 /** Cancel the filled lines and add the score
cjw851102 4:463abe5f5135 173 @brief Function to check if there are lines filled
cjw851102 4:463abe5f5135 174 @brief if one line is filled, cancel it and move the pixels above this line down and add the score
cjw851102 4:463abe5f5135 175 */
cjw851102 4:463abe5f5135 176 void cancelLine();
cjw851102 4:463abe5f5135 177
cjw851102 4:463abe5f5135 178 /**
cjw851102 4:463abe5f5135 179 Game finish animations
cjw851102 4:463abe5f5135 180 */
cjw851102 4:463abe5f5135 181 void finishAnimation();
cjw851102 4:463abe5f5135 182
cjw851102 4:463abe5f5135 183 /** User press button when game is in process
cjw851102 4:463abe5f5135 184 @brief When button pressed in the game, ask user if they want to exit the game
cjw851102 4:463abe5f5135 185 @return TRUE - exit the game FALSE - contiute the game
cjw851102 4:463abe5f5135 186 */
cjw851102 4:463abe5f5135 187 bool buttonPressedInGame();
cjw851102 4:463abe5f5135 188
cjw851102 4:463abe5f5135 189 /**Save the highest score to SD card
cjw851102 4:463abe5f5135 190 @param score - a integer number need to save to SD card
cjw851102 4:463abe5f5135 191 */
cjw851102 4:463abe5f5135 192 void save_score_SD(int score);
cjw851102 4:463abe5f5135 193
cjw851102 4:463abe5f5135 194 /**
cjw851102 4:463abe5f5135 195 Read the highest score from SD card
cjw851102 4:463abe5f5135 196 */
cjw851102 4:463abe5f5135 197 int read_score_SD();
cjw851102 4:463abe5f5135 198
cjw851102 4:463abe5f5135 199 /**
cjw851102 4:463abe5f5135 200 Complete tetris game
cjw851102 4:463abe5f5135 201 */
cjw851102 4:463abe5f5135 202 void tetis_game();
cjw851102 4:463abe5f5135 203
cjw851102 4:463abe5f5135 204
cjw851102 4:463abe5f5135 205 /////////////////////////////////////////////////
cjw851102 4:463abe5f5135 206 /// Function Definitions
cjw851102 4:463abe5f5135 207 /////////////////////////////////////////////////
cjw851102 4:463abe5f5135 208
cjw851102 4:463abe5f5135 209 void tetis_game()
cjw851102 4:463abe5f5135 210 {
cjw851102 4:463abe5f5135 211 bool exitGame; //bool variable to save the exit game decision when button pressed
cjw851102 4:463abe5f5135 212 while (1) {
cjw851102 4:463abe5f5135 213 if(g_game_flag==1) {
cjw851102 4:463abe5f5135 214 g_game_flag = 0;
cjw851102 4:463abe5f5135 215
cjw851102 4:463abe5f5135 216 exitGame=buttonPressedInGame(); //check if user press button and get the decision
cjw851102 4:463abe5f5135 217 if(exitGame) { // exit game
cjw851102 4:463abe5f5135 218 break; //jump out of while loop
cjw851102 4:463abe5f5135 219 }
cjw851102 4:463abe5f5135 220
cjw851102 4:463abe5f5135 221 pos.type = typeArray[typeCount]; //get the pattern type
cjw851102 4:463abe5f5135 222 nextTypeCount=typeCount+1;
cjw851102 4:463abe5f5135 223 if (nextTypeCount>99) { //start from the first element in type array
cjw851102 4:463abe5f5135 224 nextTypeCount=0;
cjw851102 4:463abe5f5135 225 }
cjw851102 4:463abe5f5135 226 drawPattern(typeArray[nextTypeCount],0,55,41,1);// draw next pattern on the right hand side of screen
cjw851102 4:463abe5f5135 227 if (pos.y >= -5) { // when pattern start falling, clear previous pattern
cjw851102 4:463abe5f5135 228 drawPattern(pos.type,pos.rotation,xOld,pos.y-1,0);
cjw851102 4:463abe5f5135 229 }
cjw851102 4:463abe5f5135 230
cjw851102 4:463abe5f5135 231 updateJoystick(); //get the joystick direction
cjw851102 4:463abe5f5135 232
cjw851102 4:463abe5f5135 233 top_collisionDetect(); // check if current pattern touch the top
cjw851102 4:463abe5f5135 234 if (top_collision_flag == 1) { // if touch the top, finish the game
cjw851102 4:463abe5f5135 235 red_led=1;
cjw851102 4:463abe5f5135 236 green_led=0;
cjw851102 4:463abe5f5135 237 //play sound at end of game
cjw851102 4:463abe5f5135 238 for(double i=1; i>=0; i-=0.1) {
cjw851102 4:463abe5f5135 239 buzzer = i;
cjw851102 4:463abe5f5135 240 wait(0.2);
cjw851102 4:463abe5f5135 241 }
cjw851102 4:463abe5f5135 242 buzzer = 0;
cjw851102 4:463abe5f5135 243 finishAnimation(); //finish animation
cjw851102 4:463abe5f5135 244 lcd.clear();
cjw851102 4:463abe5f5135 245 int stored_score=read_score_SD();
cjw851102 4:463abe5f5135 246 if (score>stored_score) { // if score is larger than highest score, save it to SD card
cjw851102 4:463abe5f5135 247 save_score_SD(score);
cjw851102 4:463abe5f5135 248 }
cjw851102 4:463abe5f5135 249 // show the score
cjw851102 4:463abe5f5135 250 char scoreBuffer[14];
cjw851102 4:463abe5f5135 251 sprintf(scoreBuffer,"%d",score);
cjw851102 4:463abe5f5135 252 lcd.printString("SCORE IS: ",10,2);
cjw851102 4:463abe5f5135 253 lcd.printString(scoreBuffer,35,4);
cjw851102 4:463abe5f5135 254 lcd.refresh();
cjw851102 4:463abe5f5135 255 wait(3.0);
cjw851102 4:463abe5f5135 256 lcd.clear();
cjw851102 4:463abe5f5135 257 state=0; // back to the main menu
cjw851102 4:463abe5f5135 258 break;
cjw851102 4:463abe5f5135 259 }
cjw851102 4:463abe5f5135 260
cjw851102 4:463abe5f5135 261 //move patterns according to joystick direction
cjw851102 4:463abe5f5135 262 switch(joystick.direction) {
cjw851102 4:463abe5f5135 263 case UP: // rotation
cjw851102 4:463abe5f5135 264 rotation_collision_flag = 0;
cjw851102 4:463abe5f5135 265 rotation_collisionDetect(); // check if allow rotation
cjw851102 4:463abe5f5135 266 if(rotation_collision_flag == 0) { // allow rotation
cjw851102 4:463abe5f5135 267 pos.rotation++;
cjw851102 4:463abe5f5135 268 if (pos.rotation>3) {
cjw851102 4:463abe5f5135 269 pos.rotation=0;
cjw851102 4:463abe5f5135 270 }
cjw851102 4:463abe5f5135 271 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
cjw851102 4:463abe5f5135 272 } else {// not allow rotation
cjw851102 4:463abe5f5135 273 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
cjw851102 4:463abe5f5135 274 }
cjw851102 4:463abe5f5135 275 break;
cjw851102 4:463abe5f5135 276 case DOWN: // faster moving down
cjw851102 4:463abe5f5135 277 fastmove_bottom_collision_flag = 0;
cjw851102 4:463abe5f5135 278 fastmove_bottom_collisionDetect();
cjw851102 4:463abe5f5135 279 if (fastmove_bottom_collision_flag == 0) {// allow faster move
cjw851102 4:463abe5f5135 280 pos.y +=4; // move pattern down by 4 pixels distance
cjw851102 4:463abe5f5135 281 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
cjw851102 4:463abe5f5135 282 } else {
cjw851102 4:463abe5f5135 283 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
cjw851102 4:463abe5f5135 284 }
cjw851102 4:463abe5f5135 285 break;
cjw851102 4:463abe5f5135 286 case RIGHT: // move right
cjw851102 4:463abe5f5135 287 right_collision_flag = 0;
cjw851102 4:463abe5f5135 288 right_collisionDetect(); // detect right collision
cjw851102 4:463abe5f5135 289 if( right_collision_flag == 0) { // allow move right
cjw851102 4:463abe5f5135 290 pos.x +=2;
cjw851102 4:463abe5f5135 291 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
cjw851102 4:463abe5f5135 292 } else { // not allow move right
cjw851102 4:463abe5f5135 293 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
cjw851102 4:463abe5f5135 294 right_collision_flag = 0;
cjw851102 4:463abe5f5135 295 }
cjw851102 4:463abe5f5135 296 break;
cjw851102 4:463abe5f5135 297 case LEFT: //move left
cjw851102 4:463abe5f5135 298 left_collision_flag = 0;
cjw851102 4:463abe5f5135 299 left_collisionDetect(); // detect left collision
cjw851102 4:463abe5f5135 300 if( left_collision_flag == 0) {// allow move left
cjw851102 4:463abe5f5135 301 pos.x -=2;
cjw851102 4:463abe5f5135 302 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
cjw851102 4:463abe5f5135 303 } else { // not allow move left
cjw851102 4:463abe5f5135 304 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
cjw851102 4:463abe5f5135 305 left_collision_flag = 0;
cjw851102 4:463abe5f5135 306 }
cjw851102 4:463abe5f5135 307
cjw851102 4:463abe5f5135 308 break;
cjw851102 4:463abe5f5135 309 case CENTRE: // joystick in centre
cjw851102 4:463abe5f5135 310 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
cjw851102 4:463abe5f5135 311 break;
cjw851102 4:463abe5f5135 312 case UNKNOWN:
cjw851102 4:463abe5f5135 313 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1);
cjw851102 4:463abe5f5135 314 break;
cjw851102 4:463abe5f5135 315 }
cjw851102 4:463abe5f5135 316
cjw851102 4:463abe5f5135 317 xOld = pos.x; //store previous pattern x co-codinate
cjw851102 4:463abe5f5135 318
cjw851102 4:463abe5f5135 319 bottom_collisionDetect(); // bottom collision detect
cjw851102 4:463abe5f5135 320 if (bottom_collision_flag == 0) { // no collision
cjw851102 4:463abe5f5135 321 pos.y++; // keep moving pattern down
cjw851102 4:463abe5f5135 322 buzzer = 0; // turn off buzzer
cjw851102 4:463abe5f5135 323 } else { // bottom collision
cjw851102 4:463abe5f5135 324 drawPattern(pos.type,pos.rotation,pos.x,pos.y,1); // fix pattern
cjw851102 4:463abe5f5135 325 cancelLine(); // check filled lines and add score
cjw851102 4:463abe5f5135 326 pos.x = 10; // new pattern will fall from the centre
cjw851102 4:463abe5f5135 327 pos.y = -6;
cjw851102 4:463abe5f5135 328 pos.rotation=0;
cjw851102 4:463abe5f5135 329 drawPattern(typeArray[nextTypeCount],pos.rotation,55,41,0);// clear the old next pattern show on RHS of screen
cjw851102 4:463abe5f5135 330 typeCount ++; //new type of pattern
cjw851102 4:463abe5f5135 331 if (typeCount >99) {
cjw851102 4:463abe5f5135 332 typeCount = 0;
cjw851102 4:463abe5f5135 333 }
cjw851102 4:463abe5f5135 334 }
cjw851102 4:463abe5f5135 335 lcd.refresh();
cjw851102 4:463abe5f5135 336 }
cjw851102 4:463abe5f5135 337 sleep(); // go to sleep mode unless ticker interupt
cjw851102 4:463abe5f5135 338 }
cjw851102 4:463abe5f5135 339 }
cjw851102 4:463abe5f5135 340
cjw851102 4:463abe5f5135 341
cjw851102 4:463abe5f5135 342 void init_game()
cjw851102 4:463abe5f5135 343 {
cjw851102 4:463abe5f5135 344 pos.x = 10;
cjw851102 4:463abe5f5135 345 pos.y = -6;
cjw851102 4:463abe5f5135 346 pos.rotation=0;
cjw851102 4:463abe5f5135 347 typeCount=0;
cjw851102 4:463abe5f5135 348 green_led=1; // turn on green led
cjw851102 4:463abe5f5135 349 //generate 100 random integers in the range of 0~6
cjw851102 4:463abe5f5135 350 //and store in typeArray
cjw851102 4:463abe5f5135 351 for(int i=0; i<=99; i++) {
cjw851102 4:463abe5f5135 352 typeArray[i] = rand()%7;
cjw851102 4:463abe5f5135 353 }
cjw851102 4:463abe5f5135 354
cjw851102 4:463abe5f5135 355 //gaming screen
cjw851102 4:463abe5f5135 356 lcd.drawLine(30,0,30,47,1);
cjw851102 4:463abe5f5135 357 lcd.printString("Level:",42,0);
cjw851102 4:463abe5f5135 358 lcd.printString("Score:",42,2);
cjw851102 4:463abe5f5135 359 lcd.printString("0",42,3);
cjw851102 4:463abe5f5135 360 lcd.printString("Next:",42,4);
cjw851102 4:463abe5f5135 361
cjw851102 4:463abe5f5135 362 //play sound at begining of game
cjw851102 4:463abe5f5135 363 for(double i=0; i<=1.0; i+=0.1) {
cjw851102 4:463abe5f5135 364 buzzer = i;
cjw851102 4:463abe5f5135 365 wait(0.2);
cjw851102 4:463abe5f5135 366 }
cjw851102 4:463abe5f5135 367 buzzer = 0;
cjw851102 4:463abe5f5135 368 }
cjw851102 4:463abe5f5135 369
cjw851102 4:463abe5f5135 370
cjw851102 4:463abe5f5135 371 void get_pattern(int type, int rotation)
cjw851102 4:463abe5f5135 372 {
cjw851102 4:463abe5f5135 373 for(int i=0; i<=5; i++) {
cjw851102 4:463abe5f5135 374 for(int j=0; j<=5; j++) {// patterns.getPatterns(type,rotation,j,i) return pattern[type][rotation][y][x];
cjw851102 4:463abe5f5135 375 pattern_buffer[i][j] = patterns.getPatterns(type,rotation,j,i);
cjw851102 4:463abe5f5135 376 }
cjw851102 4:463abe5f5135 377 }
cjw851102 4:463abe5f5135 378 }
cjw851102 4:463abe5f5135 379
cjw851102 4:463abe5f5135 380
cjw851102 4:463abe5f5135 381 void scan()
cjw851102 4:463abe5f5135 382 {
cjw851102 4:463abe5f5135 383 //screen has 84x48 pixels
cjw851102 4:463abe5f5135 384 for (int i=0; i<=83; i++) {
cjw851102 4:463abe5f5135 385 for (int j=0; j<=47; j++) {
cjw851102 4:463abe5f5135 386 if(lcd.getPixel(i,j)) { //if pixel is set
cjw851102 4:463abe5f5135 387 buffer[i][j] = 1;
cjw851102 4:463abe5f5135 388 } else { // pixel is clear
cjw851102 4:463abe5f5135 389 buffer[i][j] = 0;
cjw851102 4:463abe5f5135 390 }
cjw851102 4:463abe5f5135 391 }
cjw851102 4:463abe5f5135 392 }
cjw851102 4:463abe5f5135 393 }
cjw851102 4:463abe5f5135 394
cjw851102 4:463abe5f5135 395 // draw pattern at (x,y)
cjw851102 4:463abe5f5135 396 void drawPattern(int type,int rotation,int x,int y,int fill)
cjw851102 4:463abe5f5135 397 {
cjw851102 4:463abe5f5135 398 get_pattern(type,rotation); // get the pattern pixel settings, which store in pattern_buffer
cjw851102 4:463abe5f5135 399 for(int i=x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
cjw851102 4:463abe5f5135 400 for(int j=y; j <= y+5; j++) {
cjw851102 4:463abe5f5135 401 if (j>=0) {
cjw851102 4:463abe5f5135 402 if(pattern_buffer[i-x][j-y]==1) {//pixel setting is 1
cjw851102 4:463abe5f5135 403 if (fill==0) { //draw white pattern
cjw851102 4:463abe5f5135 404 if (j<=47 && i>=0) { // draw pattern inside the screen
cjw851102 4:463abe5f5135 405 lcd.clearPixel(i,j);
cjw851102 4:463abe5f5135 406 }
cjw851102 4:463abe5f5135 407 } else if (fill==1) { //draw black pattern
cjw851102 4:463abe5f5135 408 if (j<=47 && i>=0) {
cjw851102 4:463abe5f5135 409 lcd.setPixel(i,j);
cjw851102 4:463abe5f5135 410 }
cjw851102 4:463abe5f5135 411 }
cjw851102 4:463abe5f5135 412 }
cjw851102 4:463abe5f5135 413 }
cjw851102 4:463abe5f5135 414 }
cjw851102 4:463abe5f5135 415 }
cjw851102 4:463abe5f5135 416 }
cjw851102 4:463abe5f5135 417
cjw851102 4:463abe5f5135 418
cjw851102 4:463abe5f5135 419 void left_collisionDetect()
cjw851102 4:463abe5f5135 420 {
cjw851102 4:463abe5f5135 421 int left_boundary[6][6];
cjw851102 4:463abe5f5135 422 get_pattern(pos.type,pos.rotation);
cjw851102 4:463abe5f5135 423
cjw851102 4:463abe5f5135 424 /* get the left boundary pixel settings
cjw851102 4:463abe5f5135 425 e.g: if pattern is L
cjw851102 4:463abe5f5135 426 left boundary is
cjw851102 4:463abe5f5135 427 1 0 0 0 0 0
cjw851102 4:463abe5f5135 428 1 0 0 0 0 0
cjw851102 4:463abe5f5135 429 1 0 0 0 0 0
cjw851102 4:463abe5f5135 430 1 0 0 0 0 0
cjw851102 4:463abe5f5135 431 1 0 0 0 0 0
cjw851102 4:463abe5f5135 432 1 0 0 0 0 0
cjw851102 4:463abe5f5135 433 */
cjw851102 4:463abe5f5135 434 for (int j=0; j<=5; j++) { //
cjw851102 4:463abe5f5135 435 for (int i=0; i<=5; i++) {
cjw851102 4:463abe5f5135 436 if (pattern_buffer[i][j]==1) {
cjw851102 4:463abe5f5135 437 left_boundary[i][j]=1;
cjw851102 4:463abe5f5135 438 for(int k=i+1; k<=5; k++) {
cjw851102 4:463abe5f5135 439 left_boundary[k][j] = 0;
cjw851102 4:463abe5f5135 440 }
cjw851102 4:463abe5f5135 441 break;
cjw851102 4:463abe5f5135 442 } else {
cjw851102 4:463abe5f5135 443 left_boundary[i][j]=0;
cjw851102 4:463abe5f5135 444 }
cjw851102 4:463abe5f5135 445 }
cjw851102 4:463abe5f5135 446 }
cjw851102 4:463abe5f5135 447
cjw851102 4:463abe5f5135 448 //check left collision
cjw851102 4:463abe5f5135 449 int x = pos.x;
cjw851102 4:463abe5f5135 450 int y = pos.y;
cjw851102 4:463abe5f5135 451 if (x<0) { //for all the pattern, when x<0, pattern is on the most LHS of screen
cjw851102 4:463abe5f5135 452 left_collision_flag = 1;
cjw851102 4:463abe5f5135 453 } else { //check the pixel status away from left boundary for one pixel distance
cjw851102 4:463abe5f5135 454 for(int i=x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
cjw851102 4:463abe5f5135 455 for(int j=y; j <= y+5; j++) {
cjw851102 4:463abe5f5135 456 if(left_boundary[i-x][j-y]==1) {
cjw851102 4:463abe5f5135 457 if(i == 0) { // pattern at most LHS of screen
cjw851102 4:463abe5f5135 458 left_collision_flag = 1;
cjw851102 4:463abe5f5135 459 break; // don't need to check the other pixels at same x, jump out of inner for loop
cjw851102 4:463abe5f5135 460 } else if (lcd.getPixel(i-1,j)) { //check one pixel away from left boundary
cjw851102 4:463abe5f5135 461 left_collision_flag = 1;
cjw851102 4:463abe5f5135 462 break;
cjw851102 4:463abe5f5135 463 } else {
cjw851102 4:463abe5f5135 464 left_collision_flag = 0;
cjw851102 4:463abe5f5135 465 }
cjw851102 4:463abe5f5135 466 }
cjw851102 4:463abe5f5135 467 }
cjw851102 4:463abe5f5135 468 if (left_collision_flag == 1) {
cjw851102 4:463abe5f5135 469 break;// jump out of inner for loop
cjw851102 4:463abe5f5135 470 }
cjw851102 4:463abe5f5135 471 }
cjw851102 4:463abe5f5135 472 }
cjw851102 4:463abe5f5135 473 }
cjw851102 4:463abe5f5135 474
cjw851102 4:463abe5f5135 475
cjw851102 4:463abe5f5135 476 void right_collisionDetect()
cjw851102 4:463abe5f5135 477 {
cjw851102 4:463abe5f5135 478 int right_boundary[6][6];
cjw851102 4:463abe5f5135 479 get_pattern(pos.type,pos.rotation);
cjw851102 4:463abe5f5135 480
cjw851102 4:463abe5f5135 481 /* get the right boundary pixel settings
cjw851102 4:463abe5f5135 482 e.g: if pattern is L
cjw851102 4:463abe5f5135 483 left boundary is
cjw851102 4:463abe5f5135 484 0 0 1 0 0 0
cjw851102 4:463abe5f5135 485 0 0 1 0 0 0
cjw851102 4:463abe5f5135 486 0 0 1 0 0 0
cjw851102 4:463abe5f5135 487 0 0 1 0 0 0
cjw851102 4:463abe5f5135 488 0 0 0 1 0 0
cjw851102 4:463abe5f5135 489 0 0 0 1 0 0
cjw851102 4:463abe5f5135 490 */
cjw851102 4:463abe5f5135 491 for (int j=0; j<=5; j++) {
cjw851102 4:463abe5f5135 492 for (int i=5; i>=0; i--) {
cjw851102 4:463abe5f5135 493 if (pattern_buffer[i][j]==1) {
cjw851102 4:463abe5f5135 494 right_boundary[i][j]=1;
cjw851102 4:463abe5f5135 495 for(int k=i-1; k>=0; k--) {
cjw851102 4:463abe5f5135 496 right_boundary[k][j] = 0;
cjw851102 4:463abe5f5135 497 }
cjw851102 4:463abe5f5135 498 break;
cjw851102 4:463abe5f5135 499 } else {
cjw851102 4:463abe5f5135 500 right_boundary[i][j]=0;
cjw851102 4:463abe5f5135 501 }
cjw851102 4:463abe5f5135 502 }
cjw851102 4:463abe5f5135 503 }
cjw851102 4:463abe5f5135 504
cjw851102 4:463abe5f5135 505 //check right collision
cjw851102 4:463abe5f5135 506 int x = pos.x;
cjw851102 4:463abe5f5135 507 int y = pos.y;
cjw851102 4:463abe5f5135 508 for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
cjw851102 4:463abe5f5135 509 for(int j=y; j <= y+5; j++) {
cjw851102 4:463abe5f5135 510 if(right_boundary[i-x][j-y]==1) {
cjw851102 4:463abe5f5135 511 if(j>=0) {
cjw851102 4:463abe5f5135 512 if(i >= 29) { // most RHS of gaming screen
cjw851102 4:463abe5f5135 513 right_collision_flag = 1;
cjw851102 4:463abe5f5135 514 break;
cjw851102 4:463abe5f5135 515 } else if (lcd.getPixel(i+1,j)) {//check the pixel status away from right boundary for one pixel distance
cjw851102 4:463abe5f5135 516 right_collision_flag = 1;
cjw851102 4:463abe5f5135 517 break;
cjw851102 4:463abe5f5135 518 } else {
cjw851102 4:463abe5f5135 519 right_collision_flag = 0;
cjw851102 4:463abe5f5135 520 }
cjw851102 4:463abe5f5135 521 }
cjw851102 4:463abe5f5135 522 }
cjw851102 4:463abe5f5135 523 }
cjw851102 4:463abe5f5135 524 if (right_collision_flag == 1) {
cjw851102 4:463abe5f5135 525 break;
cjw851102 4:463abe5f5135 526 }
cjw851102 4:463abe5f5135 527 }
cjw851102 4:463abe5f5135 528 }
cjw851102 4:463abe5f5135 529
cjw851102 4:463abe5f5135 530
cjw851102 4:463abe5f5135 531 void bottom_collisionDetect()
cjw851102 4:463abe5f5135 532 {
cjw851102 4:463abe5f5135 533 int bot_boundary[6][6];
cjw851102 4:463abe5f5135 534 get_pattern(pos.type,pos.rotation);
cjw851102 4:463abe5f5135 535
cjw851102 4:463abe5f5135 536 /* get the left boundary pixel settings
cjw851102 4:463abe5f5135 537 e.g: if pattern is L
cjw851102 4:463abe5f5135 538 left boundary is
cjw851102 4:463abe5f5135 539 0 0 0 0 0 0
cjw851102 4:463abe5f5135 540 0 0 0 0 0 0
cjw851102 4:463abe5f5135 541 0 0 0 0 0 0
cjw851102 4:463abe5f5135 542 0 0 0 0 0 0
cjw851102 4:463abe5f5135 543 0 0 0 0 0 0
cjw851102 4:463abe5f5135 544 1 1 1 1 0 0
cjw851102 4:463abe5f5135 545 */
cjw851102 4:463abe5f5135 546 for (int i=0; i<=5; i++) {
cjw851102 4:463abe5f5135 547 for (int j=5; j>=0; j--) {
cjw851102 4:463abe5f5135 548 if (pattern_buffer[i][j]==1) {
cjw851102 4:463abe5f5135 549 bot_boundary[i][j]=1;
cjw851102 4:463abe5f5135 550 for(int k=j-1; k>=0; k--) {
cjw851102 4:463abe5f5135 551 bot_boundary[i][k] = 0;
cjw851102 4:463abe5f5135 552 }
cjw851102 4:463abe5f5135 553 break;
cjw851102 4:463abe5f5135 554 } else {
cjw851102 4:463abe5f5135 555 bot_boundary[i][j]=0;
cjw851102 4:463abe5f5135 556 }
cjw851102 4:463abe5f5135 557 }
cjw851102 4:463abe5f5135 558 }
cjw851102 4:463abe5f5135 559
cjw851102 4:463abe5f5135 560 //check bottom collision
cjw851102 4:463abe5f5135 561 int x = pos.x;
cjw851102 4:463abe5f5135 562 int y = pos.y;
cjw851102 4:463abe5f5135 563 for(int i = x; i <= x+5; i++) { //check from left
cjw851102 4:463abe5f5135 564 for(int j=y+5; j >= y; j--) { //check from bottom
cjw851102 4:463abe5f5135 565 if (j>=-1) { //start check when pattern fall in the screen
cjw851102 4:463abe5f5135 566 if(bot_boundary[i-x][j-y]==1) {
cjw851102 4:463abe5f5135 567 if(j >= 47) { // pattern at bottom
cjw851102 4:463abe5f5135 568 bottom_collision_flag = 1;
cjw851102 4:463abe5f5135 569 break; // jump out of inner for loop
cjw851102 4:463abe5f5135 570 } else if (lcd.getPixel(i,j+1)) {//check the pixel status away from bottom boundary for one pixel distance
cjw851102 4:463abe5f5135 571 bottom_collision_flag = 1;
cjw851102 4:463abe5f5135 572 break;
cjw851102 4:463abe5f5135 573 } else {
cjw851102 4:463abe5f5135 574 bottom_collision_flag = 0;
cjw851102 4:463abe5f5135 575 }
cjw851102 4:463abe5f5135 576 }
cjw851102 4:463abe5f5135 577 } else { //at bottom of screen
cjw851102 4:463abe5f5135 578 bottom_collision_flag = 0;
cjw851102 4:463abe5f5135 579 }
cjw851102 4:463abe5f5135 580 }
cjw851102 4:463abe5f5135 581 if( bottom_collision_flag == 1) {
cjw851102 4:463abe5f5135 582 break; // jump out of inner for loop
cjw851102 4:463abe5f5135 583 }
cjw851102 4:463abe5f5135 584 }
cjw851102 4:463abe5f5135 585 }
cjw851102 4:463abe5f5135 586
cjw851102 4:463abe5f5135 587
cjw851102 4:463abe5f5135 588 void rotation_collisionDetect()
cjw851102 4:463abe5f5135 589 {
cjw851102 4:463abe5f5135 590 int rotation = pos.rotation+1;
cjw851102 4:463abe5f5135 591 if (rotation>3) {
cjw851102 4:463abe5f5135 592 rotation=0;
cjw851102 4:463abe5f5135 593 }
cjw851102 4:463abe5f5135 594 get_pattern(pos.type,rotation);
cjw851102 4:463abe5f5135 595
cjw851102 4:463abe5f5135 596 //check pixel status of upcoming rotation
cjw851102 4:463abe5f5135 597 int x = pos.x;
cjw851102 4:463abe5f5135 598 int y = pos.y;
cjw851102 4:463abe5f5135 599 for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
cjw851102 4:463abe5f5135 600 for(int j=y; j <= y+5; j++) {
cjw851102 4:463abe5f5135 601 if(pattern_buffer[i-x][j-y]==1) {
cjw851102 4:463abe5f5135 602 if(i<0) { // out of LHS screen
cjw851102 4:463abe5f5135 603 rotation_collision_flag = 1;
cjw851102 4:463abe5f5135 604 } else if(lcd.getPixel(i,j)) { // there is pixel set
cjw851102 4:463abe5f5135 605 rotation_collision_flag = 1;
cjw851102 4:463abe5f5135 606 break; //jump out of inner for loop
cjw851102 4:463abe5f5135 607 } else {
cjw851102 4:463abe5f5135 608 rotation_collision_flag = 0;
cjw851102 4:463abe5f5135 609 }
cjw851102 4:463abe5f5135 610 }
cjw851102 4:463abe5f5135 611 }
cjw851102 4:463abe5f5135 612 if (rotation_collision_flag == 1) {
cjw851102 4:463abe5f5135 613 break; //jump out of inner for loop
cjw851102 4:463abe5f5135 614 }
cjw851102 4:463abe5f5135 615 }
cjw851102 4:463abe5f5135 616 }
cjw851102 4:463abe5f5135 617
cjw851102 4:463abe5f5135 618
cjw851102 4:463abe5f5135 619 void top_collisionDetect()
cjw851102 4:463abe5f5135 620 {
cjw851102 4:463abe5f5135 621 if (pos.y==-6) { //pattern is about to fall
cjw851102 4:463abe5f5135 622 bottom_collisionDetect();
cjw851102 4:463abe5f5135 623 if (bottom_collision_flag == 1) { //if can't fall
cjw851102 4:463abe5f5135 624 top_collision_flag = 1; // top collision
cjw851102 4:463abe5f5135 625 } else {
cjw851102 4:463abe5f5135 626 top_collision_flag = 0;
cjw851102 4:463abe5f5135 627 }
cjw851102 4:463abe5f5135 628 }
cjw851102 4:463abe5f5135 629 }
cjw851102 4:463abe5f5135 630
cjw851102 4:463abe5f5135 631
cjw851102 4:463abe5f5135 632 void fastmove_bottom_collisionDetect()
cjw851102 4:463abe5f5135 633 {
cjw851102 4:463abe5f5135 634 int bot_boundary[6][6];
cjw851102 4:463abe5f5135 635 get_pattern(pos.type,pos.rotation);
cjw851102 4:463abe5f5135 636
cjw851102 4:463abe5f5135 637 // get the bottom boundary pattern
cjw851102 4:463abe5f5135 638 for (int i=0; i<=5; i++) {
cjw851102 4:463abe5f5135 639 for (int j=5; j>=0; j--) {
cjw851102 4:463abe5f5135 640 if (pattern_buffer[i][j]==1) {
cjw851102 4:463abe5f5135 641 bot_boundary[i][j]=1;
cjw851102 4:463abe5f5135 642 for(int k=j-1; k>=0; k--) {
cjw851102 4:463abe5f5135 643 bot_boundary[i][k] = 0;
cjw851102 4:463abe5f5135 644 }
cjw851102 4:463abe5f5135 645 break;
cjw851102 4:463abe5f5135 646 } else {
cjw851102 4:463abe5f5135 647 bot_boundary[i][j]=0;
cjw851102 4:463abe5f5135 648 }
cjw851102 4:463abe5f5135 649 }
cjw851102 4:463abe5f5135 650 }
cjw851102 4:463abe5f5135 651
cjw851102 4:463abe5f5135 652 //check bottom collision for 4 pixel distance away from bottom boundary
cjw851102 4:463abe5f5135 653 int x = pos.x;
cjw851102 4:463abe5f5135 654 int y = pos.y;
cjw851102 4:463abe5f5135 655 for(int i = x; i <= x+5; i++) { // (x,y) is the left top point of a 6*6 square
cjw851102 4:463abe5f5135 656 for(int j=y+5; j >= y; j--) {
cjw851102 4:463abe5f5135 657 if (j>=-1) {
cjw851102 4:463abe5f5135 658 if(bot_boundary[i-x][j-y]==1) {
cjw851102 4:463abe5f5135 659 if(j >= 42) { // pattern is about to fall on the bottom
cjw851102 4:463abe5f5135 660 fastmove_bottom_collision_flag = 1;
cjw851102 4:463abe5f5135 661 break;
cjw851102 4:463abe5f5135 662 } else if (lcd.getPixel(i,j+4)) {//check bottom collision for 4 pixel distance away from bottom boundary
cjw851102 4:463abe5f5135 663 fastmove_bottom_collision_flag = 1;
cjw851102 4:463abe5f5135 664 break;
cjw851102 4:463abe5f5135 665 } else {
cjw851102 4:463abe5f5135 666 fastmove_bottom_collision_flag = 0;
cjw851102 4:463abe5f5135 667 }
cjw851102 4:463abe5f5135 668 }
cjw851102 4:463abe5f5135 669 } else {
cjw851102 4:463abe5f5135 670 fastmove_bottom_collision_flag = 0;
cjw851102 4:463abe5f5135 671 }
cjw851102 4:463abe5f5135 672 }
cjw851102 4:463abe5f5135 673 if( fastmove_bottom_collision_flag == 1) {
cjw851102 4:463abe5f5135 674 break;
cjw851102 4:463abe5f5135 675 }
cjw851102 4:463abe5f5135 676 }
cjw851102 4:463abe5f5135 677 }
cjw851102 4:463abe5f5135 678
cjw851102 4:463abe5f5135 679
cjw851102 4:463abe5f5135 680 void game_isr()
cjw851102 4:463abe5f5135 681 {
cjw851102 4:463abe5f5135 682 g_game_flag = 1;
cjw851102 4:463abe5f5135 683 }
cjw851102 4:463abe5f5135 684
cjw851102 4:463abe5f5135 685
cjw851102 4:463abe5f5135 686 void cancelLine()
cjw851102 4:463abe5f5135 687 {
cjw851102 4:463abe5f5135 688 // int linePattern[30][2]; //the pixel setting for one line(30x2 square)
cjw851102 4:463abe5f5135 689 int count; // count setting pixels two by two
cjw851102 4:463abe5f5135 690 for(int j=0; j<=46; j+=2) {
cjw851102 4:463abe5f5135 691 for(int i=0; i<=29; i++) {
cjw851102 4:463abe5f5135 692 if (lcd.getPixel(i,j)==0||lcd.getPixel(i,j+1)==0) { // there is clear pixel
cjw851102 4:463abe5f5135 693 count=0;
cjw851102 4:463abe5f5135 694 break;
cjw851102 4:463abe5f5135 695 } else if (lcd.getPixel(i,j)&&lcd.getPixel(i,j+1)) {
cjw851102 4:463abe5f5135 696 count++;
cjw851102 4:463abe5f5135 697 }
cjw851102 4:463abe5f5135 698 }
cjw851102 4:463abe5f5135 699 if(count==30) { // one line is filled
cjw851102 4:463abe5f5135 700 count=0; // reset the variable count
cjw851102 4:463abe5f5135 701 lcd.drawRect(0,j,29,1,2); //clear the line
cjw851102 4:463abe5f5135 702 buzzer = 0.5;
cjw851102 4:463abe5f5135 703 score+=10; // add the score
cjw851102 4:463abe5f5135 704 //update the score
cjw851102 4:463abe5f5135 705 char scoreBuffer[14];
cjw851102 4:463abe5f5135 706 sprintf(scoreBuffer,"%d",score);
cjw851102 4:463abe5f5135 707 lcd.printString(scoreBuffer,42,3);
cjw851102 4:463abe5f5135 708 scan();
cjw851102 4:463abe5f5135 709 // move the patterns above the line down for 2 pixels' hight
cjw851102 4:463abe5f5135 710 for (int x=0; x<=29; x++) {
cjw851102 4:463abe5f5135 711 for (int y=j; y>=0; y--) {
cjw851102 4:463abe5f5135 712 if (buffer[x][y]) {
cjw851102 4:463abe5f5135 713 lcd.clearPixel(x,y);
cjw851102 4:463abe5f5135 714 lcd.setPixel(x,y+2);
cjw851102 4:463abe5f5135 715 }
cjw851102 4:463abe5f5135 716 }
cjw851102 4:463abe5f5135 717 }
cjw851102 4:463abe5f5135 718 }
cjw851102 4:463abe5f5135 719 }
cjw851102 4:463abe5f5135 720 }
cjw851102 4:463abe5f5135 721
cjw851102 4:463abe5f5135 722
cjw851102 4:463abe5f5135 723 void finishAnimation()
cjw851102 4:463abe5f5135 724 {
cjw851102 4:463abe5f5135 725 for (int j=47; j>=0; j--) {
cjw851102 4:463abe5f5135 726 lcd.drawRect(0,j,29,1,1);
cjw851102 4:463abe5f5135 727 wait(0.05);
cjw851102 4:463abe5f5135 728 lcd.refresh();
cjw851102 4:463abe5f5135 729 }
cjw851102 4:463abe5f5135 730 }
cjw851102 4:463abe5f5135 731
cjw851102 4:463abe5f5135 732
cjw851102 4:463abe5f5135 733 bool buttonPressedInGame()
cjw851102 4:463abe5f5135 734 {
cjw851102 4:463abe5f5135 735 bool exit_game;
cjw851102 4:463abe5f5135 736 if (g_button_flag) { // user press button finish game
cjw851102 4:463abe5f5135 737 g_button_flag=0;
cjw851102 4:463abe5f5135 738 scan(); // save the currnet gaming screen
cjw851102 4:463abe5f5135 739 game.detach(); // detach the game ticker
cjw851102 4:463abe5f5135 740 lcd.clear();
cjw851102 4:463abe5f5135 741 while(1) {
cjw851102 4:463abe5f5135 742 lcd.printString("Exit The Game?",1,1);
cjw851102 4:463abe5f5135 743 lcd.printString("YES",38,3);
cjw851102 4:463abe5f5135 744 lcd.printString("NO",38,4);
cjw851102 4:463abe5f5135 745 pointer(); // invoke pointer function
cjw851102 4:463abe5f5135 746 if (g_button_flag) {
cjw851102 4:463abe5f5135 747 g_button_flag=0;
cjw851102 4:463abe5f5135 748 if(pointer_position==0) { //"YES" -exit game
cjw851102 4:463abe5f5135 749 lcd.clear();
cjw851102 4:463abe5f5135 750 state=0; // back to main menu
cjw851102 4:463abe5f5135 751 pointer_position=0;
cjw851102 4:463abe5f5135 752 exit_game=true;
cjw851102 4:463abe5f5135 753 int stored_score=read_score_SD();
cjw851102 4:463abe5f5135 754 if (score>stored_score) { // if the score is higher than highest score, save it
cjw851102 4:463abe5f5135 755 save_score_SD(score);
cjw851102 4:463abe5f5135 756 }
cjw851102 4:463abe5f5135 757 score=0; //clear socre
cjw851102 4:463abe5f5135 758 red_led=1;
cjw851102 4:463abe5f5135 759 green_led=0;
cjw851102 4:463abe5f5135 760 break;
cjw851102 4:463abe5f5135 761 } else { //"NO" - continue the game
cjw851102 4:463abe5f5135 762 exit_game=false;
cjw851102 4:463abe5f5135 763 if(state==3) { // game level is easy
cjw851102 4:463abe5f5135 764 lcd.clear();
cjw851102 4:463abe5f5135 765 for(int i=0; i<=83; i++) { // back to the gaming screen before press button
cjw851102 4:463abe5f5135 766 for(int j=0; j<=47; j++) {
cjw851102 4:463abe5f5135 767 if(buffer[i][j]) {
cjw851102 4:463abe5f5135 768 lcd.setPixel(i,j);
cjw851102 4:463abe5f5135 769 }
cjw851102 4:463abe5f5135 770 }
cjw851102 4:463abe5f5135 771 }
cjw851102 4:463abe5f5135 772 game.attach(&game_isr,0.2); // easy game
cjw851102 4:463abe5f5135 773 exit_game=false;
cjw851102 4:463abe5f5135 774 break;
cjw851102 4:463abe5f5135 775 } else if(state==4) {// game level is hard
cjw851102 4:463abe5f5135 776 lcd.clear();
cjw851102 4:463abe5f5135 777 for(int i=0; i<=83; i++) {// back to the gaming screen before press button
cjw851102 4:463abe5f5135 778 for(int j=0; j<=47; j++) {
cjw851102 4:463abe5f5135 779 if(buffer[i][j]) {
cjw851102 4:463abe5f5135 780 lcd.setPixel(i,j);
cjw851102 4:463abe5f5135 781 }
cjw851102 4:463abe5f5135 782 }
cjw851102 4:463abe5f5135 783 }
cjw851102 4:463abe5f5135 784 game.attach(&game_isr,0.1);// hard game
cjw851102 4:463abe5f5135 785 break;
cjw851102 4:463abe5f5135 786 }
cjw851102 4:463abe5f5135 787 }
cjw851102 4:463abe5f5135 788 break;
cjw851102 4:463abe5f5135 789 }
cjw851102 4:463abe5f5135 790 }
cjw851102 4:463abe5f5135 791 }
cjw851102 4:463abe5f5135 792 if(exit_game) {
cjw851102 4:463abe5f5135 793 return true;
cjw851102 4:463abe5f5135 794 } else {
cjw851102 4:463abe5f5135 795 return false;
cjw851102 4:463abe5f5135 796 }
cjw851102 4:463abe5f5135 797 }
cjw851102 4:463abe5f5135 798
cjw851102 4:463abe5f5135 799
cjw851102 4:463abe5f5135 800 int read_score_SD()
cjw851102 4:463abe5f5135 801 {
cjw851102 4:463abe5f5135 802 fp = fopen("/sd/topscore.txt", "r"); //open file
cjw851102 4:463abe5f5135 803 int stored_top_score;
cjw851102 4:463abe5f5135 804 fscanf(fp, "%d",&stored_top_score); // ensure data type matches - note address operator (&)
cjw851102 4:463abe5f5135 805 fclose(fp); // ensure you close the file after reading
cjw851102 4:463abe5f5135 806 return stored_top_score;
cjw851102 4:463abe5f5135 807 }
cjw851102 4:463abe5f5135 808
cjw851102 4:463abe5f5135 809
cjw851102 4:463abe5f5135 810 void save_score_SD(int score)
cjw851102 4:463abe5f5135 811 {
cjw851102 4:463abe5f5135 812 fp = fopen("/sd/topscore.txt", "w");
cjw851102 4:463abe5f5135 813 fprintf(fp, "%d",score); // ensure data type matches
cjw851102 4:463abe5f5135 814 fclose(fp); // ensure you close the file after writing
cjw851102 4:463abe5f5135 815 }
cjw851102 4:463abe5f5135 816 #endif