Qt实现俄罗斯方块

本文实例为大家分享了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//并创建下一个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 <QWidget>#include <QPaintEvent>#include <QPainter>#include <QPalette>#include <QPen>#include <QBrush>#include <QColor>//为了使用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 <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_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 <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();}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

销售世界上第一号的产品——不是汽车,

Qt实现俄罗斯方块

相关文章:

你感兴趣的文章:

标签云: