Su 200943147

Dependencies:   Gamepad N5110 mbed

Committer:
GS00
Date:
Thu May 04 14:20:35 2017 +0000
Revision:
9:6ee4c806f3e9
Final and Upload version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
GS00 9:6ee4c806f3e9 1 #ifndef ENGINE_H
GS00 9:6ee4c806f3e9 2 #define ENGINE_H
GS00 9:6ee4c806f3e9 3
GS00 9:6ee4c806f3e9 4 #include "Engine.h"
GS00 9:6ee4c806f3e9 5
GS00 9:6ee4c806f3e9 6 Engine::Engine()
GS00 9:6ee4c806f3e9 7 {
GS00 9:6ee4c806f3e9 8 }
GS00 9:6ee4c806f3e9 9
GS00 9:6ee4c806f3e9 10 //initialise each variable and start the game
GS00 9:6ee4c806f3e9 11 void Engine::Init(N5110 &lcd)
GS00 9:6ee4c806f3e9 12 {
GS00 9:6ee4c806f3e9 13 _Shape.Init();
GS00 9:6ee4c806f3e9 14 Boundary();
GS00 9:6ee4c806f3e9 15
GS00 9:6ee4c806f3e9 16 BottomCollision=0;
GS00 9:6ee4c806f3e9 17 LeftSideCollision=0;
GS00 9:6ee4c806f3e9 18 RightSideCollision=0;
GS00 9:6ee4c806f3e9 19 NEW=0;
GS00 9:6ee4c806f3e9 20 AddScore=0;
GS00 9:6ee4c806f3e9 21 Score=0;
GS00 9:6ee4c806f3e9 22 ScoreDisplay=0;
GS00 9:6ee4c806f3e9 23 }
GS00 9:6ee4c806f3e9 24
GS00 9:6ee4c806f3e9 25 /** ReadInput
GS00 9:6ee4c806f3e9 26 *
GS00 9:6ee4c806f3e9 27 * Read the input from the microcontroller
GS00 9:6ee4c806f3e9 28 */
GS00 9:6ee4c806f3e9 29 void Engine::ReadInput(Gamepad &pad)
GS00 9:6ee4c806f3e9 30 {
GS00 9:6ee4c806f3e9 31 d = pad.get_direction(); //direction
GS00 9:6ee4c806f3e9 32 }
GS00 9:6ee4c806f3e9 33
GS00 9:6ee4c806f3e9 34 /** Update
GS00 9:6ee4c806f3e9 35 *
GS00 9:6ee4c806f3e9 36 * A function contain all the function of the game
GS00 9:6ee4c806f3e9 37 */
GS00 9:6ee4c806f3e9 38 void Engine::Update(N5110 &lcd,Gamepad &pad)
GS00 9:6ee4c806f3e9 39 {
GS00 9:6ee4c806f3e9 40 _Shape.Rotate(pad);
GS00 9:6ee4c806f3e9 41 _Shape.Update(pad);
GS00 9:6ee4c806f3e9 42 CollisionCheck();
GS00 9:6ee4c806f3e9 43 Movement(pad);
GS00 9:6ee4c806f3e9 44 Dropping(pad);
GS00 9:6ee4c806f3e9 45 if(NEW==1) {
GS00 9:6ee4c806f3e9 46 NEW=0;
GS00 9:6ee4c806f3e9 47 NewBlock();
GS00 9:6ee4c806f3e9 48 }
GS00 9:6ee4c806f3e9 49 DeleteLine();
GS00 9:6ee4c806f3e9 50 GameOver(lcd,pad);
GS00 9:6ee4c806f3e9 51 Scores(lcd);
GS00 9:6ee4c806f3e9 52 }
GS00 9:6ee4c806f3e9 53
GS00 9:6ee4c806f3e9 54 /** Pixel
GS00 9:6ee4c806f3e9 55 *
GS00 9:6ee4c806f3e9 56 * Print the array into screen
GS00 9:6ee4c806f3e9 57 */
GS00 9:6ee4c806f3e9 58 void Engine::Pixel(N5110 &lcd)
GS00 9:6ee4c806f3e9 59 {
GS00 9:6ee4c806f3e9 60 for(int i=0; i<84; i++) {
GS00 9:6ee4c806f3e9 61 for(int j=0; j<48; j++) {
GS00 9:6ee4c806f3e9 62 if(_Shape.ShapeArray[i][j]==1) {
GS00 9:6ee4c806f3e9 63 lcd.setPixel(i,j); //Print the shape onto lcd
GS00 9:6ee4c806f3e9 64 }
GS00 9:6ee4c806f3e9 65 if(FillArray[i][j]==1) {
GS00 9:6ee4c806f3e9 66 lcd.setPixel(i,j); //Print the boundary/game state onto lcd
GS00 9:6ee4c806f3e9 67 }
GS00 9:6ee4c806f3e9 68 }
GS00 9:6ee4c806f3e9 69 }
GS00 9:6ee4c806f3e9 70 lcd.refresh(); //refresh the screen
GS00 9:6ee4c806f3e9 71 lcd.clear();
GS00 9:6ee4c806f3e9 72 }
GS00 9:6ee4c806f3e9 73
GS00 9:6ee4c806f3e9 74 /** Boundary
GS00 9:6ee4c806f3e9 75 *
GS00 9:6ee4c806f3e9 76 * Set the game plane area
GS00 9:6ee4c806f3e9 77 */
GS00 9:6ee4c806f3e9 78 void Engine::Boundary()
GS00 9:6ee4c806f3e9 79 {
GS00 9:6ee4c806f3e9 80 for(int i=0; i<84; i++) { //boundary condiction
GS00 9:6ee4c806f3e9 81 for(int j=0; j<48; j++) {
GS00 9:6ee4c806f3e9 82 FillArray[0][j]=1;
GS00 9:6ee4c806f3e9 83 FillArray[29][j]=1;
GS00 9:6ee4c806f3e9 84 }
GS00 9:6ee4c806f3e9 85 }
GS00 9:6ee4c806f3e9 86 }
GS00 9:6ee4c806f3e9 87
GS00 9:6ee4c806f3e9 88 /** CollisionCheck
GS00 9:6ee4c806f3e9 89 *
GS00 9:6ee4c806f3e9 90 * Chech if the moving block collide with the boundary or
GS00 9:6ee4c806f3e9 91 * other block in the game. When it happen set a flag(e.g command)
GS00 9:6ee4c806f3e9 92 * for the following function
GS00 9:6ee4c806f3e9 93 */
GS00 9:6ee4c806f3e9 94 void Engine::CollisionCheck()
GS00 9:6ee4c806f3e9 95 {
GS00 9:6ee4c806f3e9 96 for(int i=0; i<84; i++) {
GS00 9:6ee4c806f3e9 97 for(int j=0; j<48; j++) {
GS00 9:6ee4c806f3e9 98 if(_Shape.ShapeArray[i][j]==1) { //searching for bottom collision
GS00 9:6ee4c806f3e9 99 if(FillArray[i][j+1]==1) {
GS00 9:6ee4c806f3e9 100 BottomCollision=1; //set the flag
GS00 9:6ee4c806f3e9 101 }
GS00 9:6ee4c806f3e9 102 }
GS00 9:6ee4c806f3e9 103 if(_Shape.ShapeArray[i][47]==1) { //check if the shape block hit the bottom of the game
GS00 9:6ee4c806f3e9 104 BottomCollision=1; //set the flag
GS00 9:6ee4c806f3e9 105 }
GS00 9:6ee4c806f3e9 106 }
GS00 9:6ee4c806f3e9 107 }
GS00 9:6ee4c806f3e9 108 for(int i=0; i<84; i++) {
GS00 9:6ee4c806f3e9 109 for(int j=0; j<48; j++) {
GS00 9:6ee4c806f3e9 110 if(FillArray[i][j]==1) { //check if the shape hit the left side of the boundary
GS00 9:6ee4c806f3e9 111 if(_Shape.ShapeArray[i+1][j]==1) { //by compare the shape array with boundary array
GS00 9:6ee4c806f3e9 112 LeftSideCollision=1; //set the flag
GS00 9:6ee4c806f3e9 113 }
GS00 9:6ee4c806f3e9 114 }
GS00 9:6ee4c806f3e9 115 if(FillArray[i+1][0]==1) { //check if the shape hit the right side of the boundary
GS00 9:6ee4c806f3e9 116 if(_Shape.ShapeArray[i][j]==1) { //by compare the shape array with boundary array
GS00 9:6ee4c806f3e9 117 RightSideCollision=1; //set the flag
GS00 9:6ee4c806f3e9 118 }
GS00 9:6ee4c806f3e9 119 }
GS00 9:6ee4c806f3e9 120 }
GS00 9:6ee4c806f3e9 121 }
GS00 9:6ee4c806f3e9 122 //printf("BottomCollision=%d\n",BottomCollision);
GS00 9:6ee4c806f3e9 123 //printf("LeftCollision=%d\n",LeftSideCollision);
GS00 9:6ee4c806f3e9 124 //printf("RightCollision=%d\n",RightSideCollision);
GS00 9:6ee4c806f3e9 125 }
GS00 9:6ee4c806f3e9 126
GS00 9:6ee4c806f3e9 127 /** Movement
GS00 9:6ee4c806f3e9 128 *
GS00 9:6ee4c806f3e9 129 * The direction of horizontal movement is control by the joystick,
GS00 9:6ee4c806f3e9 130 * it shift pixel by pixel depend on the joystick direction
GS00 9:6ee4c806f3e9 131 */
GS00 9:6ee4c806f3e9 132 void Engine::Movement(Gamepad &pad)
GS00 9:6ee4c806f3e9 133 {
GS00 9:6ee4c806f3e9 134 if(d == W) {
GS00 9:6ee4c806f3e9 135 if(LeftSideCollision==1) { //if collision occured left movement stop
GS00 9:6ee4c806f3e9 136 _Shape.x=_Shape.x; //stop movement
GS00 9:6ee4c806f3e9 137 LeftSideCollision=0; //clear flag
GS00 9:6ee4c806f3e9 138 } else { //no collision, movement continue
GS00 9:6ee4c806f3e9 139 _Shape.x=_Shape.x-1; // move to the left
GS00 9:6ee4c806f3e9 140 }
GS00 9:6ee4c806f3e9 141
GS00 9:6ee4c806f3e9 142 } else if(d == E) {
GS00 9:6ee4c806f3e9 143 if(RightSideCollision==1) { //if collision occured left movement stop
GS00 9:6ee4c806f3e9 144 _Shape.x=_Shape.x; //stop movement
GS00 9:6ee4c806f3e9 145 RightSideCollision=0; //clear flag
GS00 9:6ee4c806f3e9 146 } else { //no collision, movement continue
GS00 9:6ee4c806f3e9 147 _Shape.x=_Shape.x+1; //move to the right
GS00 9:6ee4c806f3e9 148 }
GS00 9:6ee4c806f3e9 149 }
GS00 9:6ee4c806f3e9 150 // printf("x=%d\n",_Shape.x);
GS00 9:6ee4c806f3e9 151 }
GS00 9:6ee4c806f3e9 152
GS00 9:6ee4c806f3e9 153 /** Dropping
GS00 9:6ee4c806f3e9 154 *
GS00 9:6ee4c806f3e9 155 * Create the falling of each block of shape
GS00 9:6ee4c806f3e9 156 * if collision occurred as it receive the flag command
GS00 9:6ee4c806f3e9 157 * it stop the block of shape from falling
GS00 9:6ee4c806f3e9 158 */
GS00 9:6ee4c806f3e9 159 void Engine::Dropping(Gamepad &pad)
GS00 9:6ee4c806f3e9 160 {
GS00 9:6ee4c806f3e9 161 if(BottomCollision==1) { //if collision occured stop dropping
GS00 9:6ee4c806f3e9 162 BottomCollision=0; //clear flag
GS00 9:6ee4c806f3e9 163 _Shape.y=_Shape.y; //stop moving
GS00 9:6ee4c806f3e9 164 NEW=1; //Set a new flag
GS00 9:6ee4c806f3e9 165 AddScore=1; //Set a new flag
GS00 9:6ee4c806f3e9 166 pad.tone(400.0,0.1); //sound feedback
GS00 9:6ee4c806f3e9 167 } else {
GS00 9:6ee4c806f3e9 168 _Shape.y=_Shape.y+1; //continue dropping
GS00 9:6ee4c806f3e9 169 }
GS00 9:6ee4c806f3e9 170 //printf("y=%d\n",_Shape.y);
GS00 9:6ee4c806f3e9 171 }
GS00 9:6ee4c806f3e9 172
GS00 9:6ee4c806f3e9 173 /** SaveBlock
GS00 9:6ee4c806f3e9 174 *
GS00 9:6ee4c806f3e9 175 * Save the block of shape into a array
GS00 9:6ee4c806f3e9 176 */
GS00 9:6ee4c806f3e9 177 void Engine::SaveBlock()
GS00 9:6ee4c806f3e9 178 {
GS00 9:6ee4c806f3e9 179 for(int i=0; i<84; i++) {
GS00 9:6ee4c806f3e9 180 for(int j=0; j<48; j++) {
GS00 9:6ee4c806f3e9 181 if(_Shape.ShapeArray[i][j]==1) { //when there is a one in the shape array save to the game array
GS00 9:6ee4c806f3e9 182 FillArray[i][j]=_Shape.ShapeArray[i][j];
GS00 9:6ee4c806f3e9 183 }
GS00 9:6ee4c806f3e9 184 }
GS00 9:6ee4c806f3e9 185 }
GS00 9:6ee4c806f3e9 186 for(int i=0; i<84; i++) {
GS00 9:6ee4c806f3e9 187 for(int j=0; j<48; j++) {
GS00 9:6ee4c806f3e9 188 _Shape.ShapeInit[i][j]=0; //clear both array for new block
GS00 9:6ee4c806f3e9 189 _Shape.ShapeArray[i][j]=0;
GS00 9:6ee4c806f3e9 190 }
GS00 9:6ee4c806f3e9 191 }
GS00 9:6ee4c806f3e9 192 }
GS00 9:6ee4c806f3e9 193
GS00 9:6ee4c806f3e9 194 /** NewBlock
GS00 9:6ee4c806f3e9 195 *
GS00 9:6ee4c806f3e9 196 * Generate a new block when current block is in place
GS00 9:6ee4c806f3e9 197 */
GS00 9:6ee4c806f3e9 198 void Engine::NewBlock()
GS00 9:6ee4c806f3e9 199 {
GS00 9:6ee4c806f3e9 200 SaveBlock(); //run this function
GS00 9:6ee4c806f3e9 201 _Shape.x= 0; //clear variable x
GS00 9:6ee4c806f3e9 202 _Shape.y= 0; //clear variable y
GS00 9:6ee4c806f3e9 203 _Shape.New=0; //clear flag
GS00 9:6ee4c806f3e9 204 _Shape.ShapePicker(); //run this function
GS00 9:6ee4c806f3e9 205 }
GS00 9:6ee4c806f3e9 206
GS00 9:6ee4c806f3e9 207 /** Gameover
GS00 9:6ee4c806f3e9 208 *
GS00 9:6ee4c806f3e9 209 * Check the state of the game
GS00 9:6ee4c806f3e9 210 * When the game is over show on the lcd display
GS00 9:6ee4c806f3e9 211 */
GS00 9:6ee4c806f3e9 212 void Engine::GameOver(N5110 &lcd,Gamepad &pad)
GS00 9:6ee4c806f3e9 213 {
GS00 9:6ee4c806f3e9 214 for(int i=1; i<29; i++) {
GS00 9:6ee4c806f3e9 215 if(FillArray[i][2]==1) {
GS00 9:6ee4c806f3e9 216 for(int i=0; i<84; i++) {
GS00 9:6ee4c806f3e9 217 for(int j=0; j<48; j++) {
GS00 9:6ee4c806f3e9 218 FillArray[i][j]=0;
GS00 9:6ee4c806f3e9 219 _Shape.ShapeArray[i][j]=0; //clear everything when game is over
GS00 9:6ee4c806f3e9 220 _Shape.ShapeInit[i][j]=0;
GS00 9:6ee4c806f3e9 221 }
GS00 9:6ee4c806f3e9 222 }
GS00 9:6ee4c806f3e9 223 while(1) {
GS00 9:6ee4c806f3e9 224 lcd.printString("Game Over",2,2); //print to screen
GS00 9:6ee4c806f3e9 225 lcd.refresh(); //refresh the screen
GS00 9:6ee4c806f3e9 226 pad.leds_on(); //led on
GS00 9:6ee4c806f3e9 227 wait(0.1); //time delay
GS00 9:6ee4c806f3e9 228 pad.leds_off(); //led off
GS00 9:6ee4c806f3e9 229 wait(0.1); //time delay
GS00 9:6ee4c806f3e9 230 pad.tone(200.0,0.1); //sound feedback
GS00 9:6ee4c806f3e9 231 }
GS00 9:6ee4c806f3e9 232 }
GS00 9:6ee4c806f3e9 233 }
GS00 9:6ee4c806f3e9 234 }
GS00 9:6ee4c806f3e9 235
GS00 9:6ee4c806f3e9 236 /** DeleteLine
GS00 9:6ee4c806f3e9 237 *
GS00 9:6ee4c806f3e9 238 * Delete the row when it is full
GS00 9:6ee4c806f3e9 239 */
GS00 9:6ee4c806f3e9 240 void Engine::DeleteLine()
GS00 9:6ee4c806f3e9 241 {
GS00 9:6ee4c806f3e9 242 int j;
GS00 9:6ee4c806f3e9 243 for(j=0; j<48; j++) {
GS00 9:6ee4c806f3e9 244 for(int i=1; i<29; i++) {
GS00 9:6ee4c806f3e9 245 if(FillArray[i][j]==1) {
GS00 9:6ee4c806f3e9 246 Pixels++; //count the pixel
GS00 9:6ee4c806f3e9 247 }
GS00 9:6ee4c806f3e9 248 // printf("Pixels=%d\n",Pixels);
GS00 9:6ee4c806f3e9 249 }
GS00 9:6ee4c806f3e9 250 if(Pixels==28) {
GS00 9:6ee4c806f3e9 251 for(int i=1; i<29; i++) {
GS00 9:6ee4c806f3e9 252 FillArray[i][j]=0; //delete the specific line when it is full
GS00 9:6ee4c806f3e9 253 }
GS00 9:6ee4c806f3e9 254 for(int y=j-1; y>-1; y--) {
GS00 9:6ee4c806f3e9 255 for(int x=1; x<29; x++) {
GS00 9:6ee4c806f3e9 256 FillArray[x][y+1]=FillArray[x][y]; //move a row down
GS00 9:6ee4c806f3e9 257 }
GS00 9:6ee4c806f3e9 258 }
GS00 9:6ee4c806f3e9 259 Pixels=0; //clear the number of pixel
GS00 9:6ee4c806f3e9 260 Score=Score+7; //add a score of 7 when the line delete
GS00 9:6ee4c806f3e9 261 // printf("Score=%d\n",Score);
GS00 9:6ee4c806f3e9 262 } else {
GS00 9:6ee4c806f3e9 263 Pixels=0; //clear the number of pixel
GS00 9:6ee4c806f3e9 264 }
GS00 9:6ee4c806f3e9 265 }
GS00 9:6ee4c806f3e9 266 }
GS00 9:6ee4c806f3e9 267
GS00 9:6ee4c806f3e9 268 /** Scores
GS00 9:6ee4c806f3e9 269 *
GS00 9:6ee4c806f3e9 270 * Each block has a score of one and show on the screen
GS00 9:6ee4c806f3e9 271 */
GS00 9:6ee4c806f3e9 272 void Engine::Scores(N5110 &lcd)
GS00 9:6ee4c806f3e9 273 {
GS00 9:6ee4c806f3e9 274 if(AddScore==1) {
GS00 9:6ee4c806f3e9 275 AddScore=0;
GS00 9:6ee4c806f3e9 276 CurrentScore=0;
GS00 9:6ee4c806f3e9 277 for(int i=1; i<29; i++) {
GS00 9:6ee4c806f3e9 278 for(int j=0; j<48; j++) {
GS00 9:6ee4c806f3e9 279 if(FillArray[i][j]==1) {
GS00 9:6ee4c806f3e9 280 CurrentScore=CurrentScore+1; //one block has a score of one
GS00 9:6ee4c806f3e9 281 }
GS00 9:6ee4c806f3e9 282 }
GS00 9:6ee4c806f3e9 283 }
GS00 9:6ee4c806f3e9 284 }
GS00 9:6ee4c806f3e9 285 ScoreDisplay=Score+CurrentScore/4; //score calculation system
GS00 9:6ee4c806f3e9 286 // printf("ScoreDisplay=%d\n",ScoreDisplay);
GS00 9:6ee4c806f3e9 287
GS00 9:6ee4c806f3e9 288 char buffer[14]; //create a buffer to store data
GS00 9:6ee4c806f3e9 289 sprintf(buffer,"%2d",ScoreDisplay); //print the buffer with relative variable
GS00 9:6ee4c806f3e9 290 lcd.printString("Tetris",45,1);
GS00 9:6ee4c806f3e9 291 lcd.printString("Score",50,3);
GS00 9:6ee4c806f3e9 292 lcd.printString(buffer,55,4); //print the score to the screen
GS00 9:6ee4c806f3e9 293 }
GS00 9:6ee4c806f3e9 294 #endif