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:26:13 2020 +0000
Revision:
25:a7c89c54454a
Parent:
24:8868a01f4a8c
Child:
26:00e1a6076038
Final Submission

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