All there but errors need fixing

Dependencies:   mbed

Overview:

Rookie Tetris is a jigsaw style game based on the classic Tetris.

A block will appear at the top of the screen, you must move it (your options for movement are left, right and down - you cannot move up the board). The block will stop when it if placed either on the floor of the board or on-top of another block.

Your goal is to fill a complete row of the board with the blocks; when you do so the row will delete and the pattern above it will drop down. The game is over when your pattern is tall enough to reach to the top of the board!

Controls:

Use the joystick to move your block! Your block cannot move out of the parameters of the board.

Pot 2 controls the contrast of the screen.

Committer:
el18rs
Date:
Wed Jun 03 22:27:46 2020 +0000
Revision:
26:00e1a6076038
Parent:
25:a7c89c54454a
Final Submission. I have read and agreed with Statement of Academic Integrity.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
el18rs 3:522c6f850e91 1 #include "TetrisGame.h"
el18rs 3:522c6f850e91 2
el18rs 15:68114eae4053 3 volatile int iH;
el18rs 22:403759d2f093 4 volatile int iB;
el18rs 15:68114eae4053 5
el18rs 3:522c6f850e91 6 TetrisGame::TetrisGame()
el18rs 3:522c6f850e91 7 {
el18rs 15:68114eae4053 8
el18rs 3:522c6f850e91 9 }
el18rs 3:522c6f850e91 10
el18rs 3:522c6f850e91 11 TetrisGame::~TetrisGame()
el18rs 3:522c6f850e91 12 {
el18rs 15:68114eae4053 13
el18rs 3:522c6f850e91 14 }
el18rs 3:522c6f850e91 15
el18rs 26:00e1a6076038 16
el18rs 11:0183a52c1077 17 void TetrisGame::init(int speed)
el18rs 3:522c6f850e91 18 {
el18rs 4:7ddd287a5d28 19 // initialise game parameters
el18rs 11:0183a52c1077 20 _px = 40;
el18rs 11:0183a52c1077 21 _py = 4;
el18rs 9:58103274b2ab 22 _speed = speed;
el18rs 25:a7c89c54454a 23 score = 1;
el18rs 15:68114eae4053 24
el18rs 19:2ad31dbd5d11 25 _tetromino.init(_px, _py); // puts tetromino in middle
el18rs 15:68114eae4053 26
el18rs 21:6d4dd906edde 27 // printf("initiate(%i)\n",_speed);
el18rs 15:68114eae4053 28
el18rs 3:522c6f850e91 29 }
el18rs 3:522c6f850e91 30
el18rs 4:7ddd287a5d28 31
el18rs 22:403759d2f093 32 void TetrisGame::read_input(Gamepad &pad) // read inputs
el18rs 3:522c6f850e91 33 {
el18rs 3:522c6f850e91 34 _d = pad.get_direction();
el18rs 4:7ddd287a5d28 35 _mag = pad.get_mag();
el18rs 3:522c6f850e91 36 }
el18rs 3:522c6f850e91 37
el18rs 21:6d4dd906edde 38 void TetrisGame::draw(N5110 &lcd) // draw elements in lcd buffer
el18rs 3:522c6f850e91 39 {
el18rs 15:68114eae4053 40
el18rs 19:2ad31dbd5d11 41
el18rs 19:2ad31dbd5d11 42 lcd.drawRect(19, 4, 42, HEIGHT - 4, FILL_TRANSPARENT);
el18rs 19:2ad31dbd5d11 43
el18rs 25:a7c89c54454a 44 print_scores(lcd);
el18rs 25:a7c89c54454a 45
el18rs 6:39cbec524483 46 _tetromino.draw(lcd);
el18rs 15:68114eae4053 47
el18rs 25:a7c89c54454a 48
el18rs 23:cbfa9d1ee3db 49
el18rs 19:2ad31dbd5d11 50 // printf("draw (%i,%i)\n",_px,_py);
el18rs 15:68114eae4053 51
el18rs 3:522c6f850e91 52 }
el18rs 3:522c6f850e91 53
el18rs 22:403759d2f093 54 void TetrisGame::update(Gamepad &pad, N5110 &lcd) // update values
el18rs 3:522c6f850e91 55 {
el18rs 15:68114eae4053 56
el18rs 4:7ddd287a5d28 57 _tetromino.update(_d,_mag);
el18rs 15:68114eae4053 58
el18rs 25:a7c89c54454a 59 check_score(pad);
el18rs 25:a7c89c54454a 60
el18rs 21:6d4dd906edde 61 check_wall_collision(pad, lcd); // check if block has collided with the floor
el18rs 21:6d4dd906edde 62 check_tetromino_collisions(pad, lcd); // check if block has collided with an old block
el18rs 15:68114eae4053 63
el18rs 19:2ad31dbd5d11 64 // printf("update (%i,%i,%i)\n",_px,_py,_d);
el18rs 3:522c6f850e91 65 }
el18rs 4:7ddd287a5d28 66
el18rs 4:7ddd287a5d28 67
el18rs 21:6d4dd906edde 68 void TetrisGame::check_wall_collision(Gamepad &pad, N5110 &lcd) // check if block has hit floor
el18rs 3:522c6f850e91 69 {
el18rs 21:6d4dd906edde 70 Vector2D tetromino_pos = _tetromino.get_pos(); // get current positioning of block
el18rs 15:68114eae4053 71
el18rs 22:403759d2f093 72 if (tetromino_pos.y + 4 >= (HEIGHT-1) ) { // if bottom of block is on bottom boundary
el18rs 15:68114eae4053 73
el18rs 21:6d4dd906edde 74 tetromino_pos.y = (HEIGHT-1) - 4; // stop block
el18rs 15:68114eae4053 75
el18rs 22:403759d2f093 76 pad.tone(750.0,0.1); // play tone
el18rs 15:68114eae4053 77
el18rs 25:a7c89c54454a 78 score++;
el18rs 25:a7c89c54454a 79
el18rs 22:403759d2f093 80 cancel_line(lcd); // check if row is full
el18rs 15:68114eae4053 81
el18rs 15:68114eae4053 82 _tetromino.init(_px, _py); // drop new shame
el18rs 19:2ad31dbd5d11 83
el18rs 21:6d4dd906edde 84 a = tetromino_pos.x; // save positions to be drawn on next screen
el18rs 13:600a34a047ca 85 b = tetromino_pos.y;
el18rs 15:68114eae4053 86
el18rs 21:6d4dd906edde 87 floor_hit_flag = 1; // set flag so program knows to draw block on next screen
el18rs 22:403759d2f093 88
el18rs 22:403759d2f093 89 if (b <= 4) { // if pattern reaches top of screen
el18rs 22:403759d2f093 90 exit_game(lcd); // game over
el18rs 20:ad685b35a1a4 91 }
el18rs 15:68114eae4053 92
el18rs 23:cbfa9d1ee3db 93 // printf("floor hit!\n");
el18rs 15:68114eae4053 94
el18rs 4:7ddd287a5d28 95 }
el18rs 19:2ad31dbd5d11 96 // printf("wall collision\n");
el18rs 4:7ddd287a5d28 97 }
el18rs 4:7ddd287a5d28 98
el18rs 22:403759d2f093 99 void TetrisGame::check_tetromino_collisions(Gamepad &pad, N5110 &lcd) // check if block has old block beneath it
el18rs 5:53e021832adc 100 {
el18rs 21:6d4dd906edde 101 Vector2D tetromino_pos = _tetromino.get_pos(); // get current position of block
el18rs 5:53e021832adc 102
el18rs 5:53e021832adc 103 if (
el18rs 22:403759d2f093 104 (lcd.getPixel(tetromino_pos.x, tetromino_pos.y + 4) == 1) ||
el18rs 17:70d45e9e44a8 105 (lcd.getPixel(tetromino_pos.x + 1, tetromino_pos.y + 4) == 1) ||
el18rs 17:70d45e9e44a8 106 (lcd.getPixel(tetromino_pos.x + 2, tetromino_pos.y + 4) == 1) ||
el18rs 22:403759d2f093 107 (lcd.getPixel(tetromino_pos.x + 3, tetromino_pos.y + 4) == 1) // if any of the 4 pixels directly below the block are black
el18rs 5:53e021832adc 108 ) {
el18rs 15:68114eae4053 109
el18rs 22:403759d2f093 110 pad.tone(1000.0,0.1); // play tone
el18rs 25:a7c89c54454a 111
el18rs 25:a7c89c54454a 112 score++;
el18rs 25:a7c89c54454a 113
el18rs 21:6d4dd906edde 114 cancel_line(lcd); // check if row is full
el18rs 15:68114eae4053 115
el18rs 21:6d4dd906edde 116 _tetromino.init(_px, _py); // drop new block
el18rs 15:68114eae4053 117
el18rs 21:6d4dd906edde 118 a = tetromino_pos.x; // save positioning of old block
el18rs 16:fca1bbb06c44 119 b = tetromino_pos.y;
el18rs 16:fca1bbb06c44 120
el18rs 21:6d4dd906edde 121 floor_hit_flag = 1; // set flag so program knows to draw block on next screen
el18rs 22:403759d2f093 122
el18rs 22:403759d2f093 123 if (b <= 4) { // if pattern reaches top of screen
el18rs 22:403759d2f093 124 exit_game(lcd); // game over
el18rs 20:ad685b35a1a4 125 }
el18rs 15:68114eae4053 126
el18rs 23:cbfa9d1ee3db 127 // printf("blocks stacked!\n");
el18rs 19:2ad31dbd5d11 128 }
el18rs 19:2ad31dbd5d11 129 // printf("tetromino collision\n");
el18rs 5:53e021832adc 130 }
el18rs 6:39cbec524483 131
el18rs 22:403759d2f093 132 void TetrisGame::cancel_line(N5110 &lcd) // check if row is full, if it is then delete line and drop pattern down
el18rs 6:39cbec524483 133 {
el18rs 22:403759d2f093 134 for(int j=4; j<=46; j++) {
el18rs 20:ad685b35a1a4 135 for(int i=20; i<=60; i++) {
el18rs 21:6d4dd906edde 136 if (lcd.getPixel(i,j)==0) { // if the pixel is empty the counting stops and exits loop (row is not full)
el18rs 15:68114eae4053 137 count=0;
el18rs 23:cbfa9d1ee3db 138 // printf("line not full\n");
el18rs 15:68114eae4053 139 break;
el18rs 22:403759d2f093 140 } else if (lcd.getPixel(i,j)==1) { // if the pixel is full carries on counting
el18rs 15:68114eae4053 141 count ++;
el18rs 23:cbfa9d1ee3db 142 // printf("counting... count=%i\n",count);
el18rs 6:39cbec524483 143 }
el18rs 22:403759d2f093 144 if (count==48) { // if gets to end of line
el18rs 22:403759d2f093 145 count = 0;
el18rs 22:403759d2f093 146 printf("line full\n");
el18rs 22:403759d2f093 147 // lcd.drawRect(20,j,40,4,FILL_WHITE); // clear line
el18rs 22:403759d2f093 148 c = j;
el18rs 23:cbfa9d1ee3db 149 d = i;
el18rs 22:403759d2f093 150 clear_line_flag = 1;
el18rs 22:403759d2f093 151 floor_hit_flag = 0;
el18rs 23:cbfa9d1ee3db 152 // printf("line canceled!\n");
el18rs 22:403759d2f093 153 }
el18rs 6:39cbec524483 154 }
el18rs 15:68114eae4053 155 }
el18rs 23:cbfa9d1ee3db 156 // printf("cancel line\n");
el18rs 15:68114eae4053 157 }
el18rs 6:39cbec524483 158
el18rs 15:68114eae4053 159 void TetrisGame::exit_game(N5110 &lcd)
el18rs 15:68114eae4053 160 {
el18rs 15:68114eae4053 161 lcd.clear();
el18rs 23:cbfa9d1ee3db 162 lcd.printString(" GAME OVER \n",0, 3);
el18rs 15:68114eae4053 163 lcd.refresh();
el18rs 15:68114eae4053 164 wait(10);
el18rs 23:cbfa9d1ee3db 165 // printf("game over!\n");
el18rs 15:68114eae4053 166 lcd.clear();
el18rs 15:68114eae4053 167 lcd.printString(" press RESET ",0,6);
el18rs 15:68114eae4053 168 lcd.refresh();
el18rs 23:cbfa9d1ee3db 169 // printf("press reset!\n");
el18rs 15:68114eae4053 170 exit(1.0);
el18rs 15:68114eae4053 171 }
el18rs 15:68114eae4053 172
el18rs 15:68114eae4053 173 void TetrisGame::fallenblocks(N5110 &lcd, int iH)
el18rs 15:68114eae4053 174 {
el18rs 15:68114eae4053 175 for (int i=0; i<=iH; i++) {
el18rs 15:68114eae4053 176 x0 = X[i];
el18rs 15:68114eae4053 177 y0 = Y[i];
el18rs 16:fca1bbb06c44 178 lcd.drawRect(x0, y0, 4, 4, FILL_BLACK);
el18rs 19:2ad31dbd5d11 179 // printf("block drawn\n");
el18rs 15:68114eae4053 180 }
el18rs 22:403759d2f093 181 }
el18rs 22:403759d2f093 182
el18rs 23:cbfa9d1ee3db 183 void TetrisGame::currentscreen(N5110 &lcd)
el18rs 23:cbfa9d1ee3db 184 {
el18rs 23:cbfa9d1ee3db 185 for (int i=0; i<=83; i++) {
el18rs 23:cbfa9d1ee3db 186 for (int j=0; j<=47; j++) {
el18rs 23:cbfa9d1ee3db 187 if(lcd.getPixel(i,j)) { //if pixel is set
el18rs 23:cbfa9d1ee3db 188 buffer[i][j] = 1;
el18rs 23:cbfa9d1ee3db 189 } else { // pixel is clear
el18rs 23:cbfa9d1ee3db 190 buffer[i][j] = 0;
el18rs 23:cbfa9d1ee3db 191 }
el18rs 23:cbfa9d1ee3db 192 }
el18rs 23:cbfa9d1ee3db 193 }
el18rs 23:cbfa9d1ee3db 194 }
el18rs 23:cbfa9d1ee3db 195
el18rs 23:cbfa9d1ee3db 196 void TetrisGame::clearline(N5110 &lcd, int iB)
el18rs 22:403759d2f093 197 {
el18rs 22:403759d2f093 198 for (int i=0; i<=iB; i++) {
el18rs 22:403759d2f093 199 z0 = Z[i];
el18rs 23:cbfa9d1ee3db 200 q0 = Q[i];
el18rs 25:a7c89c54454a 201 lcd.drawRect(20, z0, 40, 4, FILL_WHITE); // clear rectagle over where the full row is
el18rs 25:a7c89c54454a 202 }
el18rs 25:a7c89c54454a 203 currentscreen(lcd);
el18rs 25:a7c89c54454a 204 for (int x=20; x<=60; x++) {
el18rs 25:a7c89c54454a 205 for (int y=c; y>=0; y--) { // screen above row that was removed
el18rs 25:a7c89c54454a 206 if (buffer[x][y]) { // buffer of screen
el18rs 25:a7c89c54454a 207 lcd.setPixel(x,y, false); // remove pixel
el18rs 25:a7c89c54454a 208 lcd.setPixel(x,y+4); // replace with pixel above it
el18rs 25:a7c89c54454a 209 }
el18rs 25:a7c89c54454a 210 }
el18rs 22:403759d2f093 211 }
el18rs 23:cbfa9d1ee3db 212 }
el18rs 23:cbfa9d1ee3db 213
el18rs 25:a7c89c54454a 214 void TetrisGame::print_scores(N5110 &lcd) // print score on screen
el18rs 23:cbfa9d1ee3db 215 {
el18rs 25:a7c89c54454a 216 char Sbuffer[14];
el18rs 25:a7c89c54454a 217 int n, _score = score;
el18rs 25:a7c89c54454a 218 n=sprintf (Sbuffer, "%d",_score);
el18rs 25:a7c89c54454a 219 // printf ("[%s] is a string %d chars long\n",Sbuffer,n);
el18rs 25:a7c89c54454a 220 lcd.printString(Sbuffer,65,3);
el18rs 23:cbfa9d1ee3db 221 }
el18rs 23:cbfa9d1ee3db 222
el18rs 25:a7c89c54454a 223 void TetrisGame::check_score(Gamepad &pad) // update scores
el18rs 23:cbfa9d1ee3db 224 {
el18rs 23:cbfa9d1ee3db 225 if ( clear_line_flag == 1) {
el18rs 25:a7c89c54454a 226 score+=10;
el18rs 23:cbfa9d1ee3db 227 }
el18rs 15:68114eae4053 228 }