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 //並創建下一個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(); }
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- None Found