知方号

知方号

Qt实现俄罗斯方块

Qt实现俄罗斯方块

Qt实现俄罗斯方块

最近在学习Qt,用它来进行图形界面的开发还是很方便的,想着做一个小游戏来锻炼一下自己,就想到了小时候玩的俄罗斯方块。折腾了一段时间,虽然界面做的不美观,但是总算是实现了基本的功能。

首先我写了一个俄罗斯方块的类Tetris,通过这个类来进行这个游戏的数据的处理;然后游戏窗口是继承的QWidget类,用来显示游戏的方块;“下一个方块”窗口也是继承的QWidget类,用来显示下一个方块;控制提示和分数的显示用的QLabel。然后将将这些控件整合到继承自QMainWindow的mainWindow类。运行的结果如下:

Tetris类:一共有7中不同形状的方块(如下图),每个方块由四个方格组成,Block结构体用来存储方块的方格坐、中心方格坐标、ID等数据,移动中的方块和下移个方块都是通过这个结构体来操作的;已经落下的方块的方格存储在二维数组box[][]中,x坐标从左到右为正方向,y坐标从上到下为正方向(如下图)。

项目源文件 tetris.htetris.cpptetrisbox.htetrisbox.cppnexttetris.hnexttetris.cppmainwindow.hmainwindow.cpp tetris.h #ifndef TETRIS_H#define TETRIS_H//为了获得随机数#include #include #define MAXX 10 //显示窗口的横向格数#define MAXY 20 //显示窗口的竖向格数#define NEXTMAXX 6 //“下一个”显示窗口的横向格数#define NEXTMAXY 6 //“下一个”显示窗口的竖向格数#define WIDTH 30 //单格的宽度#define HEIGHT 30 //单格的高度#define INTERVAL 4 //单格之间的间隔#define COUNT 4 //每个方块的格数//Block结构体:一个方块struct Block{ int x[COUNT]; //方块单格的x坐标 int y[COUNT]; //方块单格的y坐标 int centerX; //方块的中心x坐标 int centerY; //方块的中心y坐标 int ID; //方块的ID};class Tetris{public: Tetris(); void createBlock(); //创建当前方块 Block getNextBlock(); //获得下一个方块 Block getBlock(); //获得当前方块 int getScore(); //获得分数 int getBox(int x, int y); //获得相应坐标的状态 bool rotate(); //旋转 bool moveToLeft(); //向左移动 bool moveToRight(); //向右移动 bool moveToBottom(); //向下移动 bool isEnd(); //判断是否结束 void killLines(); //消去整行 void clear(); //重新初始化 static int getWidth(); //获得窗口的宽度 static int getHeight(); //获得窗口的高度 static int getNextWidth(); //获得“下一个”窗口的宽度 static int getNextHeight(); //获得“下一个”窗口的高度private: void createNextBlock(); //创建下一个方块 bool move(int dx, int dy); //是否可以移动 void blockToBox(); //将block中的数据转移到box中 bool isRotatable(); //是否可以旋转 int getFirstFullLine(); //获得第一个整行private: int score; //分数 Block block; //当前方块 Block nextBlock; //下一个方块 int box[MAXX][MAXY];//方格的坐标系 1表示右方格,0表示没有方格};#endif // TETRIS_H Tetris.cpp #include "tetris.h"Tetris::Tetris(){ //初始化随机数发生器 srand(unsigned(time(NULL))); //初始化成员变量 score = 0; for (int i = 0; i < MAXX; i++) { for (int j = 0; j < MAXY; j++) { box[i][j] = 0; } } for (int i = 0; i < COUNT; i++) { block.x[i] = -1; block.y[i] = -1; } block.centerX = -1; block.centerY = -1; block.ID = 0; //创建下一个方块 createNextBlock();}//创建当前方块//将上一次生成的下一个方块nextBlock复制给block//并创建下一个nextBlockvoid Tetris::createBlock(){ //nextBlock复制给block for (int i = 0; i < COUNT; i++) { block.x[i] = nextBlock.x[i]; block.y[i] = nextBlock.y[i]; } block.centerX = nextBlock.centerX; block.centerY = nextBlock.centerY; block.ID = nextBlock.ID; //创建下一个nextblock createNextBlock();}//返回下一个方块Block Tetris::getNextBlock(){ return nextBlock;}//返回当前方块Block Tetris::getBlock(){ return block;}//返回当前分数int Tetris::getScore(){ return score;}//返回坐标(x,y)的值,以判断是否右方格int Tetris::getBox(int x, int y){ return box[x][y];}//旋转当前方块//旋转成功返回true,否则返回falsebool Tetris::rotate(){ if (isRotatable()) { return true; } else { return false; }}//将当前方块向左移动一格//成功返回true,否则返回falsebool Tetris::moveToLeft(){ if (move(-1, 0)) { return true; } else { return false; }}//将当前方块向右移动一格//成功返回true,否则返回falsebool Tetris::moveToRight(){ if (move(1, 0)) { return true; } else { return false; }}//将方块向下移动一格//成功返回true, 游戏结束返回falsebool Tetris::moveToBottom(){ if (!move(0, 1)) { //移动不成功 blockToBox(); //将当前方块复制到box中 killLines(); //消行 //判断是否结束 //否则创建新的方块 if(isEnd()) { return false; } else { createBlock(); } } return true;}//判断游戏是否结束//结束条件为第一行有方格bool Tetris::isEnd(){ int j = 0; for (int i = 0; i < MAXX; i++) { if (box[i][j] == 1) { return true; } } return false;}//消掉整行并进行分数奖励void Tetris::killLines(){ int count = 0; //一次消掉的行数 //通过getFirstFullLine()函数获得从上到下第一个整行 //并将其上的行向下平移一行,达到消行的效果 int temp = 0; while ((temp = getFirstFullLine()) != -1) { for (int j = temp; j >0; j--) { for (int i = 0; i < MAXX; i++) { box[i][j] = box[i][j-1]; } } count++; } //消行的分数奖励 score += count * count * 10;}//对成员变量进行初始化,重新开始游戏void Tetris::clear(){ //初始化 score = 0; srand(unsigned(time(NULL))); for (int i = 0; i < MAXX; i++) { for (int j = 0; j < MAXY; j++) { box[i][j] = 0; } } for (int i = 0; i < COUNT; i++) { block.x[i] = -1; block.y[i] = -1; } block.centerX = -1; block.centerY = -1; block.ID = 0; //创建下一个方块 createNextBlock();}//获得游戏窗口的宽度int Tetris::getWidth(){ return MAXX * WIDTH + (MAXX - 1) * INTERVAL;}//获得游戏窗口的高度int Tetris::getHeight(){ return MAXY * HEIGHT + (MAXY - 1) * INTERVAL;}//获得“下一个”窗口的宽度int Tetris::getNextWidth(){ return NEXTMAXX * WIDTH + (NEXTMAXX - 1) * INTERVAL;}//获得“下一个”窗口的高度int Tetris::getNextHeight(){ return NEXTMAXY * WIDTH + (NEXTMAXY - 1) * INTERVAL;}//创建“下一个”方块void Tetris::createNextBlock(){ int centerX = (MAXX - 1) / 2; //中心x坐标 int ID = rand() % 7; //获得0 - 6的随机数 //根据不同的随机数创建方块 switch (ID) { case 0: //## //## nextBlock.x[0] = centerX; nextBlock.x[1] = centerX; nextBlock.x[2] = centerX + 1; nextBlock.x[3] = centerX + 1; nextBlock.y[0] = -2; nextBlock.y[1] = -1; nextBlock.y[2] = -2; nextBlock.y[3] = -1; nextBlock.centerX = 0; nextBlock.centerY = 0; nextBlock.ID = 0; break; case 1: //#### // nextBlock.x[0] = centerX - 1; nextBlock.x[1] = centerX; nextBlock.x[2] = centerX + 1; nextBlock.x[3] = centerX + 2; nextBlock.y[0] = -1; nextBlock.y[1] = -1; nextBlock.y[2] = -1; nextBlock.y[3] = -1; nextBlock.centerX = centerX; nextBlock.centerY = -1; nextBlock.ID = 1; break; case 2: //## // ## nextBlock.x[0] = centerX - 1; nextBlock.x[1] = centerX; nextBlock.x[2] = centerX; nextBlock.x[3] = centerX + 1; nextBlock.y[0] = -2; nextBlock.y[1] = -2; nextBlock.y[2] = -1; nextBlock.y[3] = -1; nextBlock.centerX = centerX; nextBlock.centerY = -2; nextBlock.ID = 2; break; case 3: // ## //## nextBlock.x[0] = centerX; nextBlock.x[1] = centerX + 1; nextBlock.x[2] = centerX - 1; nextBlock.x[3] = centerX; nextBlock.y[0] = -2; nextBlock.y[1] = -2; nextBlock.y[2] = -1; nextBlock.y[3] = -1; nextBlock.centerX = centerX; nextBlock.centerY = -2; nextBlock.ID = 3; break; case 4: //# //### nextBlock.x[0] = centerX - 1; nextBlock.x[1] = centerX - 1; nextBlock.x[2] = centerX; nextBlock.x[3] = centerX + 1; nextBlock.y[0] = -2; nextBlock.y[1] = -1; nextBlock.y[2] = -1; nextBlock.y[3] = -1; nextBlock.centerX = centerX; nextBlock.centerY = -1; nextBlock.ID = 4; break; case 5: // # //### nextBlock.x[0] = centerX + 1; nextBlock.x[1] = centerX - 1; nextBlock.x[2] = centerX; nextBlock.x[3] = centerX + 1; nextBlock.y[0] = -2; nextBlock.y[1] = -1; nextBlock.y[2] = -1; nextBlock.y[3] = -1; nextBlock.centerX = centerX; nextBlock.centerY = -1; nextBlock.ID = 5; break; case 6: // # //### nextBlock.x[0] = centerX; nextBlock.x[1] = centerX - 1; nextBlock.x[2] = centerX; nextBlock.x[3] = centerX + 1; nextBlock.y[0] = -2; nextBlock.y[1] = -1; nextBlock.y[2] = -1; nextBlock.y[3] = -1; nextBlock.centerX = centerX; nextBlock.centerY = -1; nextBlock.ID = 6; break; default: break; }}//可以移动就对block进行变换,返回true//否则返回falsebool Tetris::move(int dx, int dy){ int newX[COUNT]; int newY[COUNT]; int newCenterX; int newCenterY; for (int i = 0; i < COUNT; i++) { newX[i] = block.x[i] + dx; newY[i] = block.y[i] + dy; //对变换后的坐标进行判定 //x坐标超出范围返回false if (newX[i] < 0 || newX[i] >= MAXX) { return false; } //y坐标在0 - MAXY之间就对box中的状态进行判定 //box中为1则返回false if (newY[i] >=0 && newY[i] < MAXY) { if (box[newX[i]][newY[i]] == 1) { return false; } }//y坐标超出最大值返回false else if (newY[i] >= MAXY) { return false; } } newCenterX = block.centerX + dx; newCenterY = block.centerY + dy; //满足条件就将新的x和y坐标赋值给block for (int i = 0; i < COUNT; i++) { block.x[i] = newX[i]; block.y[i] = newY[i]; } block.centerX = newCenterX; block.centerY = newCenterY; return true;}//可以旋转就对block进行变换,返回true//否则返回falsebool Tetris::isRotatable(){ int newX[COUNT]; int newY[COUNT]; int newCenterX; int newCenterY; if (block.ID == 0) { return false; } for (int i = 0; i < COUNT; i++) { int nx = block.x[i] - block.centerX; int ny = block.y[i] - block.centerY; newX[i] = nx * 0 + ny * (-1) + block.centerX; newY[i] = nx * 1 + ny * 0 + block.centerY; //对变换后的坐标进行判定 //x坐标超出范围返回false if (newX[i] < 0 || newX[i] >= MAXX) { return false; } //y坐标在0 - MAXY 之间就对box中的状态进行判定 //box中为1则返回false if (newY[i] >=0 && newY[i] < MAXY) { if (box[newX[i]][newY[i]] == 1) { return false; } }//y坐标超过最大值返回false else if (newY[i] >= MAXY) { return false; } } newCenterX = block.centerX; newCenterY = block.centerY; //满足条件后进行block的赋值 for (int i = 0; i < COUNT; i++) { block.x[i] = newX[i]; block.y[i] = newY[i]; } block.centerX = newCenterX; block.centerY = newCenterY; return true;}//将block中数据复制到box中void Tetris::blockToBox(){ for (int i = 0; i < COUNT; i++) { int x = block.x[i]; int y = block.y[i]; if (y >= 0) { box[x][y] = 1; } }}//获得第一个整行的行数,并返回int Tetris::getFirstFullLine(){ //这里j从1开始就好 for (int j = 0; j < MAXY; j++) { bool judgement = true; for (int i = 0; i < MAXX; i++) { if (box[i][j] == 0) { judgement = false; break; } } if (judgement) { return j; } } return -1;} tetrisbox.h #ifndef TETRISBOX_H#define TETRISBOX_H#include #include #include #include #include #include #include //为了使用Block#include "tetris.h"class TetrisBox : public QWidget{ Q_OBJECTpublic: explicit TetrisBox(QWidget *parent = nullptr); void updateTetris(Tetris tetris); //更新数据和视图 void paintEvent(QPaintEvent *event); //绘制视图signals:public slots:private: Block block; //用来储存Tetris中block的数据 int box[MAXX][MAXY]; //用来存储Tetris中box的数据};#endif // TETRISBOX_H tetrisbox.cpp #include "tetrisbox.h"TetrisBox::TetrisBox(QWidget *parent) : QWidget(parent){ //对block初始化 for (int i = 0; i < COUNT; i++) { block.x[i] = -1; block.y[i] = -1; } block.centerX = -1; block.centerY = -1; block.ID = -1; //对box初始化 for (int i = 0; i < MAXX; i++) { for (int j = 0; j < MAXY; j++) { box[i][j] = 0; } } //设置本游戏窗口的宽度和高度 //并设置背景为黑色 int w = Tetris::getWidth(); int h = Tetris::getHeight(); setFixedSize(w, h); setPalette(QPalette(Qt::black)); setAutoFillBackground(true);}void TetrisBox::updateTetris(Tetris tetris){ //更新block block = tetris.getBlock(); //更新box for (int i = 0; i < MAXX; i++) { for (int j = 0; j < MAXY; j++) { box[i][j] = tetris.getBox(i, j); } } repaint();}void TetrisBox::paintEvent(QPaintEvent *event){ QPainter painter(this); QPen pen; QBrush brush; pen.setStyle(Qt::SolidLine); pen.setColor(QColor(255, 255, 255)); brush.setStyle(Qt::SolidPattern); brush.setColor(QColor(255, 255, 255)); painter.setPen(pen); painter.setBrush(brush); //绘制box中的内容 for (int i = 0; i < MAXX; i++) { for (int j = 0; j < MAXY; j++) { if (box[i][j] == 1) { int x = i * WIDTH + i * INTERVAL; int y = j * HEIGHT + j * INTERVAL; painter.drawRect(x, y, WIDTH, HEIGHT); } } } //绘制block中的内容 for (int i = 0; i < COUNT; i++) { int x = block.x[i]; int y = block.y[i]; int x1 = x * WIDTH + x * INTERVAL; int y1 = y * HEIGHT + y * INTERVAL; painter.drawRect(x1, y1, WIDTH, HEIGHT); }} nexttetrisbox.h #ifndef NEXTTETRISBOX_H#define NEXTTETRISBOX_H#include #include #include #include #include #include #include #include "tetris.h"#define RESTX (MAXX - NEXTMAXX) / 2 //方块x坐标的转换常数#define RESTY 4 //方块y坐标的转换常数class NextTetrisBox : public QWidget{ Q_OBJECTpublic: explicit NextTetrisBox(QWidget *parent = nullptr); void updateNextTetris(Tetris tetris); //更新“下一个”的数据和视图 void paintEvent(QPaintEvent *event); //绘制视图signals:public slots:private: Block nextBlock; //“下一个”方块};#endif // NEXTTETRISBOX_H nexttetris.cpp #include "nexttetrisbox.h"NextTetrisBox::NextTetrisBox(QWidget *parent) : QWidget(parent){ //初始化nextBlock for (int i = 0; i < COUNT; i++) { nextBlock.x[i] = -1; nextBlock.y[i] = -1; } nextBlock.centerX = -1; nextBlock.centerY = -1; nextBlock.ID = 0; //设置本“下一个”窗口的宽度和高度 //并设置背景为黑色 int w = Tetris::getNextWidth(); int h = Tetris::getNextHeight(); setFixedSize(w, h); setPalette(QPalette(Qt::black)); setAutoFillBackground(true);}void NextTetrisBox::updateNextTetris(Tetris tetris){ nextBlock = tetris.getNextBlock(); for (int i = 0; i < COUNT; i++) { nextBlock.x[i] -= RESTX; nextBlock.y[i] += RESTY; } //重新绘制 repaint();}void NextTetrisBox::paintEvent(QPaintEvent *event){ QPainter painter(this); QPen pen; QBrush brush; pen.setStyle(Qt::SolidLine); pen.setColor(QColor(255, 255, 255)); brush.setStyle(Qt::SolidPattern); brush.setColor(QColor(255, 255, 255)); painter.setPen(pen); painter.setBrush(brush); //绘制nextBlock中的内容 for (int i = 0; i < COUNT; i++) { int x = nextBlock.x[i]; int y = nextBlock.y[i]; int x1 = x * WIDTH + x * INTERVAL; int y1 = y * HEIGHT + y * INTERVAL; painter.drawRect(x1, y1, WIDTH, HEIGHT); }} mainwindow.h #ifndef MAINWINDOW_H#define MAINWINDOW_H#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tetris.h"#include "tetrisbox.h"#include "nexttetrisbox.h"//游戏的状态#define STATUS_ON 0 //游戏正常进行#define STATUS_PAUSE 1 //游戏暂停#define STATUS_OFF 2 //游戏未开始#define STATUS_END 3 //游戏结束class MainWindow : public QMainWindow{ Q_OBJECTpublic: MainWindow(QWidget *parent = 0); ~MainWindow(); void keyPressEvent(QKeyEvent *event); //响应键盘事件 void changeEvent(QEvent *event); //窗口最小化后暂停 void updateScore(); //更新分数的数据和显示public slots: void onTimer();private: int status; //游戏状态 Tetris tetris; //俄罗斯方块类对象 QTimer *timer; //计时器 TetrisBox *tetrisBox; //游戏窗口 NextTetrisBox *nextTetrisBox; //“下一个”窗口 QGridLayout *mainLayout; //mainLayout QLabel *nextTetrisLabel; //“下一个”窗口的标签 QLabel *controlLabel; //“控制”标签 QLabel *w_controlLabel; //W键的标签 QLabel *s_controlLabel; //S键的标签 QLabel *a_controlLabel; //A键的标签 QLabel *d_controlLabel; //D键的标签 QLabel *h_controlLabel; //H键的标签 QLabel *j_controlLabel; //J键的标签 QLabel *c_controlLabel; //C键的标签 QLabel *m_controlLabel; //M键的标签 QLabel *scoreTitleLabel; //分数标题标签 QLabel *scoreLabel; //分数标签(用来显示分数)};#endif // MAINWINDOW_H mainwindow.cpp #include "mainwindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ //创建对象 tetrisBox = new TetrisBox; nextTetrisBox = new NextTetrisBox; nextTetrisLabel = new QLabel(tr("下一个:")); controlLabel = new QLabel(tr("控制:")); w_controlLabel = new QLabel(tr("W-旋转")); s_controlLabel = new QLabel(tr("S-向下移动")); a_controlLabel = new QLabel(tr("A-向左移动")); d_controlLabel = new QLabel(tr("D-向右移动")); h_controlLabel = new QLabel(tr("H-开始")); j_controlLabel = new QLabel(tr("J-暂停")); c_controlLabel = new QLabel(tr("C-重新开始")); m_controlLabel = new QLabel(tr("M-结束游戏")); scoreTitleLabel = new QLabel(tr("得分:")); scoreLabel = new QLabel(tr("0")); mainLayout = new QGridLayout; //设置mainLayout的水平和横向的间隔为20 mainLayout->setHorizontalSpacing(20); mainLayout->setVerticalSpacing(20); //设置mainLayout居中 mainLayout->setAlignment(Qt::AlignCenter); //添加各个widget mainLayout->addWidget(tetrisBox, 0, 0, 14, 1); mainLayout->addWidget(nextTetrisLabel, 0, 1); mainLayout->addWidget(nextTetrisBox, 1, 1, 1, 2); mainLayout->addWidget(controlLabel, 5, 1); mainLayout->addWidget(w_controlLabel, 6, 1); mainLayout->addWidget(s_controlLabel, 6, 2); mainLayout->addWidget(a_controlLabel, 7, 1); mainLayout->addWidget(d_controlLabel, 7, 2); mainLayout->addWidget(h_controlLabel, 8, 1); mainLayout->addWidget(j_controlLabel, 8, 2); mainLayout->addWidget(c_controlLabel, 9, 1); mainLayout->addWidget(m_controlLabel, 9, 2); mainLayout->addWidget(scoreTitleLabel, 12, 1); mainLayout->addWidget(scoreLabel, 12, 2); //因为mainWindow已有一个layout,所以不能直接将mainLayout //设置到mainWindow中,需要先将mainLayout设置为一个widget的layout //在将widget设置为mainLayout的centralWidget QWidget *widget = new QWidget(this); widget->setLayout(mainLayout); setCentralWidget(widget); //设置窗口背景为灰色 setPalette(Qt::gray); //设置窗口在电脑屏幕上居中 QDesktopWidget *desktopWidget = QApplication::desktop(); int w = (desktopWidget->width() - this->width()) / 2; int h = 5; move(w, h); //初始化 status = STATUS_OFF; nextTetrisBox->updateNextTetris(tetris); setWindowTitle(tr("Game_Tetris - OFF")); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));}MainWindow::~MainWindow(){}//相应键盘事件void MainWindow::keyPressEvent(QKeyEvent *event){ //W键-进行旋转并更新游戏窗口内容 if (event->key() == Qt::Key_W) { if (tetris.rotate()) { //需要游戏状态为:正常进行 if (status == STATUS_ON) { tetrisBox->updateTetris(tetris); } } } //A键-将方块向左移动并更新游戏窗口内容 else if (event->key() == Qt::Key_A) { //需要游戏状态为:正常进行 if (status == STATUS_ON) { if (tetris.moveToLeft()) { tetrisBox->updateTetris(tetris); } } } //S键-将方块向下移动并更新游戏窗口内容 else if (event->key() == Qt::Key_S) { //需要游戏状态:正常进行 if (status == STATUS_ON) { if (tetris.moveToBottom()) { tetrisBox->updateTetris(tetris); nextTetrisBox->updateNextTetris(tetris); updateScore(); } else //游戏结束 { //计时器停止 timer->stop(); //输出结束提示 QString str; str += QString("Game Over! Your Score is: %1!").arg(tetris.getScore()); QMessageBox::information(this, tr("Game Over"), str); //更改游戏状态为:游戏结束 status = STATUS_END; setWindowTitle(tr("Game_Tetris - END")); } } } //D键-将方块向右移动并更新游戏窗口内容 else if (event->key() == Qt::Key_D) { //需要游戏状态为:正常进行 if (status == STATUS_ON) { if (tetris.moveToRight()) { tetrisBox->updateTetris(tetris); } } } //H键-开始游戏 //不同状态的相应: //之前状态 之后状态 //游戏暂停 -> 正常进行 //还未开始 -> 正常进行 //游戏结束 -> 正常进行 else if (event->key() == Qt::Key_H) { if (status == STATUS_PAUSE) { timer->start(500); status = STATUS_ON; setWindowTitle(tr("Game_Tetris - ON")); } else if (status == STATUS_OFF) { //初始化窗口视图 tetris.createBlock(); tetrisBox->updateTetris(tetris); nextTetrisBox->updateNextTetris(tetris); updateScore(); status = STATUS_ON; setWindowTitle(tr("Game_Tetris - ON")); timer->start(500); } else if (status == STATUS_END) { //初始化tetris tetris.clear(); tetris.createBlock(); tetrisBox->updateTetris(tetris); nextTetrisBox->updateNextTetris(tetris); updateScore(); status = STATUS_ON; setWindowTitle(tr("Game_Tetris - ON")); timer->start(500); } } //J键-游戏暂停 else if (event->key() == Qt::Key_J) { //需要游戏状态为:正常进行 if (status == STATUS_ON) { timer->stop(); status = STATUS_PAUSE; setWindowTitle(tr("Game_Tetris - PAUSE")); } } //C键-重新开始游戏 else if (event->key() == Qt::Key_C) { timer->stop(); tetris.clear(); tetrisBox->updateTetris(tetris); nextTetrisBox->updateNextTetris(tetris); updateScore(); status = STATUS_OFF; setWindowTitle(tr("Game_Tetris - OFF")); } //M键-关闭游戏 else if (event->key() == Qt::Key_M) { close(); }}void MainWindow::onTimer(){ if(tetris.moveToBottom()) { tetrisBox->updateTetris(tetris); nextTetrisBox->updateNextTetris(tetris); updateScore(); } else { timer->stop(); QString str; str += QString("Game Over! Your Score is: %1!").arg(tetris.getScore()); QMessageBox::information(this, tr("Game Over"), str); status = STATUS_END; setWindowTitle(tr("Game_Tetris - END")); }}void MainWindow::updateScore(){ QString str; int score = tetris.getScore(); str += QString("%1").arg(score); scoreLabel->setText(str);}//若窗口最小化就停止计时器void MainWindow::changeEvent(QEvent *event){ if (event->type() != QEvent::WindowStateChange) { return; } if (windowState() == Qt::WindowMinimized) { timer->stop(); }} main.cpp #include "mainwindow.h"#include int main(int argc, char *argv[]){ QApplication a(argc, argv); MainWindow w; w.show(); return a.exec();}

C++

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lizi9903@foxmail.com举报,一经查实,本站将立刻删除。