QT实现俄罗斯方块游戏

您所在的位置:网站首页 俄罗斯方块的核心规则 QT实现俄罗斯方块游戏

QT实现俄罗斯方块游戏

2024-07-11 06:45| 来源: 网络整理| 查看: 265

1. 程序简介:

 俄罗斯方块是一款大家都熟系的小游戏,这里给大家一步一步的详细介绍如何用QT开发这个游戏,并通过这款游戏的开发练习,进一步熟系"qvector.h","qpoint.h", "qmap.h","qpainter.h",  QTime, KeyEvent,QMediaPlaylist,QMediaPlayer 等的用法。

 

2. 程序说明:

       2.1  程序界面:分游戏区,提示区,控制区

                  

         2.2 程序实现功能:

              1) 绘制游戏区域;

              2) 按开始按钮开始游戏;

              3) 按方向键实现方块的左移,右移,翻转;

              4) 按空格键实现方块移动到最底部;

              5) 当一行排满之后,自动消行。消行后,自动记分。

              6) 每满1000分后,自动升到下一级,每升一级,方块向下移动的速度加快;

              7) 记录游戏时间;

              8) 按暂停按钮暂停游戏;

              9) 按结束按钮结束游戏;

              10)单击音乐按扭打开/关闭背景音乐;

 

3.  程序设计

      3. 1  创建项目

           3.1.1 新建一个以QMainWindow 为基类的Qt Widgets Application,取名 Teris;

                    

 

                   

       3.1.2. 构建项目

                 1)单击项目模式,在弹出的窗口中选择构建套件,后按Configure Project 按扭。

                     

                     

 

                 构建完成后,程序处于可编译状态。

                 

 

 

 

      3.2  UI设计

              3.2.1 移除窗口中的菜单栏,状态栏;

              3.2.2 按下面示意图来设计窗体。

                  

 

                  注意:

                       a. 主窗体大小设置为1000*800;

                       b. widgetGameArea 窗体大小设为600*800;

                       c. 先设计排版好控件后,再按Gridlayout;

                       d. 3 个Pushbutton  和CheckBox 的Focus Policy 设置为NoFocus;

                 3.2.3 在mainwindow.cpp 中填加如下语句: 

1 setFixedSize(1000,800); //设置窗体为固定大小 2 setWindowTitle(tr("俄罗斯方块"));//设置窗体标题

                 3.2.4 运行效果如下

                 

 

    3.3  创建方块类:

      3.3.1  新建一个C++ Class 文件,取名为Item, 并勾选#include Widget, #include QObject , Add Q_OBJECT.

                  

 

 

         3.3.2   在item.h中添加头文件 ,定义方块类形枚举变量,在GameArea 类体中添加 public 变量,成员函数;

#ifndef ITEM_H #define ITEM_H #include #include #include "qvector.h" #include "qpoint.h" #include "qpainter.h" enum ITEM_TYPE{ ITEM_1 = 0, //长条 ITEM_2, //山字形 ITEM_3, //手枪形1 ITEM_4, //手枪形2 ITEM_5, //田 ITEM_6, //Z字形1 ITEM_MAX, }; class Item { public: Item(){} Item(ITEM_TYPE t,int nShape = 0); //类型和形状构造 ~Item(void){}; void InitNew(int nSeed = 0); //根据随机因子nSeed, 初始化方块类形的种类及形状 void InitItem(ITEM_TYPE t,int nShape = 0); //根据方块类形的种类及形状,初始化方块类形的坐标 void ChangeShape(int nAdd = 1); //改变文块类形形状, 默认按顺续改变形状 void AddPoints(QVector& points); //添加方块格子坐标 void Move(int x,int y); //横向移动x格,竖向移动y格 void MoveTo(int x,int y); //移动到位置(x,y)格 void MoveDown(int nRow,int y); //第nRow行以上的部分下移y行,用在消格之后 void Draw(QPainter& painter,int nStartX,int nStartY,int nW,int nH); //根据方块格子的起始位置座标,长,宽,画出方块格子 void DeleteRow(int y); //删除第y行 public: QVector mPoints; //方块类型4个方块格子的坐标 QPoint mPos; //方块类型原点 ITEM_TYPE mType; //方块类型,有6种类型 int mShape; //方块形状,每个类型方块有1~4个形状态, }; #endif // ITEM_H

            3.3.3  在item.cpp 中实现成员函数。

#include "item.h" #include Item::Item(ITEM_TYPE t,int nShape) //类型和形状构造 { mPos=QPoint(0,0); // 初始化方块类型的原点坐标 InitItem(t,nShape); // 根据方块类形的种类及形状,初始化方块类形的坐标 } void Item::InitNew(int nSeed) { if(nSeed == 0) { //如果没有随机因子,就使用当前时间作随机因子 qsrand(QTime::currentTime().msec()); //qsrand, 使用Seed 生成随机数。后面的Qrand 使用相同的随机数序列 } else { //传入随机因子 qsrand(nSeed); } ITEM_TYPE t = (ITEM_TYPE)(qrand()%ITEM_MAX); // 产生随机的方块类型 int s = qrand()%4; // 产生随机的形状 //qDebug()widgetGameArea,&GameArea::sigUpdateScore,this,&MainWindow::slotUpdateScore); connect(ui->widgetGameArea,&GameArea::sigUpdateLevel,this,&MainWindow::slotUpdateLevel); connect(ui->widgetGameArea,&GameArea::sigUdateTimeEslape,this,&MainWindow::slotUpdateTime);

       3.4.6  在mainwindow.cpp 中实现槽函数,slotUpdateScoe,slotUpdateLevel,slotUpdateTime

void MainWindow::slotUpdateScore(int nScore) { ui->labelScore->setText(QString::number(nScore)); } void MainWindow::slotUpdateLevel(int nSpeed) { ui->labelSpeed->setText(QString::number(nSpeed)); } void MainWindow::slotUpdateTime(int tplayed) { int sec=tplayed/1000; ui->labelTime->setText(QString::number(sec)+mTime); }

        3.4.7 把Widgetgamearea 窗体提升为自定义类GameArea  

                          

 

    3.5  提示区设计, 提示区主要包含一个窗体,用于产生和提示下一个方块。

           3.5.1 新建一个C++ Clarss 文件 , 取名为NextArea , 并勾选#include Widget, #include QObject , Add Q_OBJECT

              

 

 

 

 

           3.5.2  在nextarea.h 中 添加 "item.h" 头文件, 并在类体中添加如下代码           

 

class NextArea { Q_OBJECT public: explicit NextArea(QWidget *parent = nullptr); //构造函数 protected: void paintEvent(QPaintEvent *); //绘图事件 public slots: void slotUpdateNextItem(ITEM_TYPE t,int nShape); //产生下一个方块的槽函数 private: Item mItem; //item 类变量 };

      3.5.3 在nextarea.cpp 中添加类的成员函数

void NextArea::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setBrush(QColor("#FFDEAD")); painter.setPen(QPen(QColor(Qt::black),1)); int xStart = 80; //为了绘制在显示下一个方块区域的中部 int yStart = 15; int w = 20; int h = 20; foreach (QPoint pt, mItem.mPoints) { int x = xStart + pt.x() * w; int y = yStart + pt.y() * h; painter.drawRect(x, y, w, h); } update(); } void NextArea::slotUpdateNextItem(ITEM_TYPE t, int nShape) { mItem.InitItem(t,nShape); }

           3.5.3  在maiwindow.cpp  中添加头文件 nextarea.h, 在构造函数中添加如下代码

//GameArea通过信号sigUpdateNextItem 通知 NextArea 刷新下一个元素 connect(ui->widgetGameArea,&GameArea::sigUpdateNextItem,ui->widgetNextArea,&NextArea::slotUpdateNextItem);

         3.5.4  提升nextarea 窗口为NextArea 类    

                  

 

 

    3.6  操作区程序设计:

            3.6.1 背景音乐:

                 3.6.1.1 在程序目录下,创建一个文件夹,命名为media, 拷备3个mp3 音乐到此文件夹下,并改名子为1.mp3, 2.mp3, 3.mp3

             

 

            3.6.1.2  在teris.pro 添加      QT +=multimedia

            3.6.1.3  在mainwindow.h 中添加头文件   QMediaPlaylist  和 QMediaPlayer.  并定义私有变量

QMediaPlaylist *Playlist; QMediaPlayer *player;

           3.6.1.4  在Mainwindow.cpp 的构造函数中, 添加如下代码

Playlist =new QMediaPlaylist; //创建新的播放清单 player=new QMediaPlayer; //创建新的播放器 Playlist->addMedia(QUrl::fromLocalFile("D:/MyQT/Teris/media/1.mp3")); //往播放清单中添加音乐文件 Playlist->addMedia(QUrl::fromLocalFile("D:/MyQT/Teris/media/2.mp3")); Playlist->addMedia(QUrl::fromLocalFile("D:/MyQT/Teris/media/3.mp3")); Playlist->setCurrentIndex(0); //设置默认播放开始位置 Playlist->setPlaybackMode(QMediaPlaylist::Loop); //设置循环播放 player->setPlaylist(Playlist); //播放清单导入播放器 player->play(); //播放器开播

 

     3.6.1.5 单击Checkbox , 添加槽, 

void MainWindow::on_checkBox_stateChanged(int arg1) { if(arg1) player->play(); else player->stop(); }

      3.6.2  控制按键设计:

         3.6.2.1  在mainwindow.h 中添加私有变量:

bool Gamestatus; //记录游戏状态 int mTime; //记录游戏时间

        3.6.2.2 在mainwindow.cpp 的构造函数添加语名,初始化按键和游戏状态

ui->pbPause->setEnabled(false); ui->pbStop->setEnabled(false); ui->checkBox->setChecked(true); Gamestatus=true;

       3.6.2.3 分别添加3个按键的槽函数

void MainWindow::on_pbStart_clicked() { Gamestatus=true; ui->widgetGameArea->NewGame(); ui->pbStart->setEnabled(false); ui->pbPause->setEnabled(true); ui->pbStop->setEnabled(true); } void MainWindow::on_pbPause_clicked() { ui->widgetGameArea->PauseGame(Gamestatus); bool ok; if(Gamestatus) { ui->pbPause->setText(tr("重新开始")); Gamestatus=false; mTime=(ui->labelTime->text()).toInt(&ok,10); } else { ui->pbPause->setText(tr("暂停")); Gamestatus=true; } } void MainWindow::on_pbStop_clicked() { ui->widgetGameArea->StopGame(); ui->pbStop->setEnabled(false); ui->pbStart->setEnabled(true); ui->pbPause->setEnabled(false); }

       3.6.2.4 添加键盘事件, 响应按键动作, 在mainwindow.h 中添加头文件KeyEvent 和KeypressEvent

protected: void keyPressEvent(QKeyEvent *e);

      3.6.2.5  在mainwindow.cpp , 实现函数

void MainWindow::keyPressEvent(QKeyEvent *e) { ui->widgetGameArea->KeyPressed(e->key()); QMainWindow::keyPressEvent(e); }

 

介绍完成,运行程序玩起



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3