Qt实现俄罗斯方块

Dulcea ·
更新时间:2024-09-21
· 753 次阅读

本文实例为大家分享了Qt实现俄罗斯方块,供大家参考,具体内容如下

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

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

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

项目源文件

tetris.h

tetris.cpp

tetrisbox.h

tetrisbox.cpp

nexttetris.h

nexttetris.cpp

mainwindow.h

mainwindow.cpp

tetris.h

#ifndef TETRIS_H #define TETRIS_H //为了获得随机数 #include <cstdlib> #include <ctime> #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 //并创建下一个nextBlock void 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,否则返回false bool Tetris::rotate() { if (isRotatable()) { return true; } else { return false; } } //将当前方块向左移动一格 //成功返回true,否则返回false bool Tetris::moveToLeft() { if (move(-1, 0)) { return true; } else { return false; } } //将当前方块向右移动一格 //成功返回true,否则返回false bool Tetris::moveToRight() { if (move(1, 0)) { return true; } else { return false; } } //将方块向下移动一格 //成功返回true, 游戏结束返回false bool 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 //否则返回false bool 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 //否则返回false bool 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 <QWidget> #include <QPaintEvent> #include <QPainter> #include <QPalette> #include <QPen> #include <QBrush> #include <QColor> //为了使用Block #include "tetris.h" class TetrisBox : public QWidget { Q_OBJECT public: 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 <QWidget> #include <QWidget> #include <QPaintEvent> #include <QPen> #include <QBrush> #include <QPainter> #include <QColor> #include "tetris.h" #define RESTX (MAXX - NEXTMAXX) / 2 //方块x坐标的转换常数 #define RESTY 4 //方块y坐标的转换常数 class NextTetrisBox : public QWidget { Q_OBJECT public: 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 <QMainWindow> #include <QMainWindow> #include <QPainter> #include <QEvent> #include <QPaintEvent> #include <QPen> #include <QBrush> #include <QColor> #include <QKeyEvent> #include <QTimer> #include <QGridLayout> #include <QLabel> #include <QMessageBox> #include <QDesktopWidget> #include <QApplication> #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_OBJECT public: 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!\nYour 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!\nYour 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 <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }



俄罗斯方块

需要 登录 后方可回复, 如果你还没有账号请 注册新账号