Objective
A week ago want to do a Tetris game, because want to use C + + implementation, but also constrained by the interface, so studied a few days of QT. Yesterday began to work jointly with a sleepless night, finally is done, the taste, even if only they know.
Brief introduction
Tetris, C++,QT.
Features: Regular Tetris with: block rotation, left, right, drop acceleration, line, hint the next piece of style, etc. have been realized. It also realizes the function of scoring and pausing.
Game process
Time out
Game Over
Implementation ideas
Referring to Tetris, a little bit of trouble is only three points
1. Block rotation
#1 # # #1 # # #11 # #### #### # #1 # 111 ##### #### #11 # # #1 # # #1 # #### #111 #1 # # ####
The above four small matrices we can easily see, it is the L-shape pattern of four different forms, with 4*4 matrix to unify them, and then the careful little partner will also find that their order is also in accordance with anti-clockwise rotation of the arrangement.
Then add us to the above four small matrices numbered 1,2,3,4.
So obviously 1-rotation---2--rotation----3--rotation--4-Rotary->1
If we open up a next array to hold the block corresponding to the rotated block number.
Then next[1] = 2; NEXT[2] = 3; NEXT[3] = 4; NEXT[4] = 1;
Extrapolate, other shape blocks are the same.
2. Collision Detection
Above, we use a four-dimensional small matrix to represent the block, we can set a center of gravity, simply use the upper left corner (0, 0) point as the center of gravity Bar.
This center of gravity is just a relative point that corresponds to the actual map.
We ignore the small matrix, only focus on the point of gravity, through the center of Gravity point where the coordinates of the map, it is possible to find other points in the map coordinates.
In this way, each time the action block, the block will be transformed to the location of the map to compare, through a simple judgment, can be drawn whether there is a repetition, if repeated, you can move, otherwise not.
3. Block Auto-drop
This is the easiest to solve, QT has a Qtimer class, has a timing function, set a certain time interval, triggering the TimerEvent event. In the event, do what you want to do.
Code composition
All code only implements three classes
1. Board Game Map Information
class Board{ Public:intScore;//Current score intMaxscore;//Highest score intTime//The interval between each drop intWidth//Map width intHeight//Map HighBlock *block;//Falling blocks Charmap[ -][ -];//Save map InformationBoard (int,int);voidConfirm ();//Update the drop-down block to map BOOLIsend ();//Determine if the game is over};
2. Block block information and operation
class Block{ Public:Charblocks[ -][5][5];//blocks of various types intnext[ -];//analog pointing for block rotationQt::globalcolor color[ -];//color of each type of block intX//block center of gravity start coordinates intYintType//Block ID intNexttype;//Next block IDBoard *board; Block (Board *);//Constructors voidTonext ();//change block ID voidMoveUp ();//Deformation voidMoveRight ();//Acceleration voidMoveLeft ();//Shift left voidMoveDown ();//Right Shift BOOLDetectint);//Collision Detection};
3. MainWindow Game Interface Section
public QMainWindow{ Q_OBJECTpublic: bool flag;//判断是否暂停状态 QTimer *timer;//定时器 Board *board;//游戏所用地图类 0); void paintEvent(QPaintEvent *event);//绘制界面 void keyPressEvent(QKeyEvent *);//键盘事件处理signals:public slots: voidtimerEvent();//定时事件private:};
Core code
A rough estimate of the total amount of code is about 500 lines, so here only the part that you think is the core, the complete project file and executable program will be uploaded to Git, the following will give a link. Interested friends go down a bit.
Collision detection
BOOLBlock::d Etect (intFlag) {//Gets the target state of the current operation: target coordinates, target block type. intNEXTX, Nexty, Nexttype;//0,1,2,3 corresponds to the upper or lower Switch(flag) { Case0: NEXTX = x; Nexty = y; Nexttype = next[type]; Break; Case1: NEXTX = x+1; Nexty = y; Nexttype =type; Break; Case2: NEXTX = x; Nexty = y-1; Nexttype =type; Break; Case3: NEXTX = x; Nexty = y+1; Nexttype =type; Break; } for(intI=0; I<4; i++) for(intJ=0; J<4; J + +) {//tx,ty represents the actual location of the map to which the i,j corresponds. inttx = Nextx+i;intty = nexty+j;//Border processing if(TX <0|| Tx > Board->height+1|| Ty <0|| Ty > Board->width+1)Continue;//If the block coincides with the map wall, a collision occurs if(Blocks[nexttype][i][j]! =' # '&& (Ty = =0|| Ty = = Board->width+1))return false;if(Blocks[nexttype][i][j]! =' # '&& board->Map[TX] [Ty]! =' # ')return false; }return true; }
Map information update and row scoring operation after block sink
voidBoard::confirm () {//update blocks to map for(intI=0; i<4; i++) for(intj=0; j<4; J + +) {inttx = Block->x + i;intTy = Block->y + j;if(tx<1|| tx > Height | | Ty <1|| Ty > Width)Continue;if(Block->blocks[block->type][i][j]! =' # ')Map[TX] [Ty] = block->blocks[block->type][i][j]; }//Eliminate the complete line and count the number of rows intCNT =0; for(intI=height; i>=1; i--) {BOOLFlag =false; for(intj=1; j<=width; J + +)if(MapI [j] = =' # ') {flag =true; Break; }if(flag)Continue; cnt++; for(intJ=i; j>=1; j--) for(intk=1; k<=width; k++)Map[j] [K] =Map[J-1][K]; }//one block per drop plus 5 pointsScore + =5;//According to the number of simultaneous elimination rows of the exponential type score //1-10 2-20 3-40 4-80 if(CNT) score + =Ten*(1<<CNT);//Update maximum value in real timeMaxscore =STD:: Max (Maxscore, score);//Each drop of a block, time interval minus 2Time-=2;if(Time <0) Time =0;//Update blockBlock->tonext ();}
Full code
My GitHub Links:
Https://github.com/shiyi1996/algorithm/tree/master/eluosi
Haha, the process of sharing results is always enjoyable.
Finally, if the Youdao friends find that there are errors in the place, also hope to point out.
If there is a better writing can also exchange one or two, we progress together!
Qt5 Implement Tetris (detailed comment)