最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

世界简讯:Qt项目-翻金币游戏

来源:博客园
  • 项目概述
  • 项目预览
  • 项目框架
  • 项目代码
  • 项目总结

-项目概述-


(相关资料图)

Qt基础课程完结项目,完成一款小游戏并封装:翻金币游戏,通过点击金币进行翻面,让所有金币为同一面就游戏通过进入下一关。

过程中会使用前面学到的 “信号和槽”,“Qt图片资源显示”,“Qt播放音频”,“Qt绘图函数”,“Qt消息控件”等等知识。是一次前面所学知识的汇总。

-项目预览-

-程序框架-

框架如下,(因为这个项目完成有些时间了,现在才记录下来,流程部分是看的当时的程序注释,有些不明白的地方可以私信我)

-代码资源下载-

运行平台:

主界面代码:

1 #include "mainwindow.h" 2 #include "ui_mainwindow.h" 3 #include  4 #include  5 #include  6 #include  7 #include  8 #include "mybutton.h" 9 10 11 MainWindow::MainWindow(QWidget *parent) :12     QMainWindow(parent),13     ui(new Ui::MainWindow)14 {15     ui->setupUi(this);16 17 18 //-------------------------------------------------------------主窗口设置-------------------------------------------------------------------//19     // 1.主窗口场景设置20     this->setFixedSize(360, 360*1.7);21     this->setWindowIcon(QPixmap(":/res/Coin0001.png"));22     this->setWindowTitle("翻金币");23 24     // 2.主窗口控件设置25     connect(ui->actionExit, &QAction::triggered, [=](){26         this->close();27     });28 29     // 3.创建关卡选择界面指针对象,同时监听关卡按钮前线发回的信号30     this->CustomWidget = new ChooseCustoms;31 32     connect(CustomWidget, &ChooseCustoms::ChooseCustomBacksig, [=](){33         this->setGeometry(CustomWidget->geometry());34         CustomWidget->hide();35         this->show();36     });37 38     // 4.创建并移动开始按钮对象39     MyButton *startBtn = new MyButton(":/res/MenuSceneStartButton.png");40     startBtn->setParent(this);41     startBtn->move((this->width() - startBtn->width())*0.5, this->height()*0.7);42 43     // 5.播放开始按钮点击音效44     QSound *startSound = new QSound(":/res/TapButtonSound.wav", this);45     46     connect(startBtn, &MyButton::clicked, [=](){47         qDebug() << "点击了开始按钮";        48         startBtn->jumpDown();       49         startSound->play();50         startBtn->jumpUp();51 52         QTimer::singleShot(400, this, [=](){ this->hide(); CustomWidget->show(); });53     });54 }55 56 57 58 59 //-------------------------------------------------------------主窗口绘图事件绘制界面-------------------------------------------------------------------//60 void MainWindow::paintEvent(QPaintEvent *)61 {62     QPainter painter(this);63 64     // 绘制主场景背景界面65     QPixmap pix;66     pix.load(":/res/海滩.jpg");67     painter.drawPixmap(QRect(0, 0, this->width(), this->height()), pix);68 69     // 绘制主场景图标70     pix.load(":/res/Title.png");71     pix = pix.scaled(pix.width()*0.7, pix.height()*0.7);72     painter.drawPixmap(10, 30, pix.width(), pix.height() , pix);73 }74 75 76 MainWindow::~MainWindow()77 {78     delete ui;79 }

关卡选择界面函数:

1 #include "choosecustoms.h"  2 #include   3 #include   4 #include   5 #include   6 #include   7 #include   8   9 ChooseCustoms::ChooseCustoms(QWidget *parent) : QMainWindow(parent) 10 { 11 //-------------------------------------------------------------主窗口设置-------------------------------------------------------------------// 12     // 1.场景以及图标,标题设置 13     this->setFixedSize(360, 360*1.7); 14     this->setWindowIcon(QPixmap(":/res/Coin0001.png")); 15     this->setWindowTitle("翻金币"); 16  17     // 2.创建菜单栏,创建关闭按钮 18     QMenuBar *bar = this->menuBar(); 19     this->setMenuBar(bar); 20     QMenu *startMenu = bar->addMenu("开始"); 21     QAction *quitAction = startMenu->addAction("退出"); 22  23     connect(quitAction, &QAction::triggered, [=](){ 24         this->hide(); 25     }); 26  27     // 3.返回按钮,返回按钮点击后返回的信号 28     MyButton *retBtn = new MyButton(":/res/BackButton.png", ":/res/BackButtonSelected.png"); 29     retBtn->setParent(this); 30     retBtn->move(this->width()-retBtn->width(), this->height()-retBtn->height()); 31  32  33     connect(retBtn, &MyButton::clicked, [=](){ 34         qDebug() << "点击了返回按钮"; 35         QSound *retSound = new QSound(":/res/BackButtonSound.wav", this); 36         retSound->play(); 37         QTimer::singleShot(400, this, [=](){ emit this->ChooseCustomBacksig(); }); 38     }); 39  40 //-------------------------------------------------------------for循环创建关卡选择按钮----------------------------------------------------------// 41     // 4.创建关卡选择按钮 42     for(int i = 0; i < 20; i++) 43     { 44         // 绘制按钮图标 45         MyButton *customBtn = new MyButton(":/res/LevelIcon.png"); 46         customBtn->setParent(this); 47         customBtn->move(45 + (i%4)*70 , 150 + (i/4)*70);  // 我们要一个4x5的矩阵 48         customBtnArray[i] = customBtn; 49  50         // 关联每一个按钮的启动函数 51         connect(customBtn, &MyButton::clicked, [=](){ 52  53             // 关卡选择按钮上锁,其余的按钮不能点击 54             for(int i = 0; i < 20; i++) 55             { 56                 customBtnArray[i]->isclick = true; 57             } 58             qDebug() << "选择了" << i+1 << "关卡"; 59             if(this->coinfligwidget == NULL) 60             {               61                 customBtn->jumpDown(); 62                 customBtn->jumpUp(); 63                 QSound *chooseSound = new QSound(":/res/TapButtonSound.wav", this); 64                 chooseSound->play(); 65  66                 QTimer::singleShot(400, this, [=](){ 67                     this->hide(); 68                     this->coinfligwidget = new CoinFligWidget(i+1); 69                     coinfligwidget->setGeometry(this->geometry()); 70                     coinfligwidget->show(); 71  72                     // 关卡选择按钮解锁,其余的按钮可以点击 73                     for(int i = 0; i < 20; i++) 74                     { 75                         customBtnArray[i]->isclick = false; 76                     } 77  78                     connect(coinfligwidget, &CoinFligWidget::CoinFligBacksig, [=](){ 79                         this->setGeometry(coinfligwidget->geometry()); 80                         this->show(); 81                         delete coinfligwidget; 82                         coinfligwidget = NULL; 83                     }); 84                 }); 85             }            86         }); 87  88         // 绘制按钮数字 89         QLabel *label = new QLabel; 90         label->setParent(this); 91         label->setFixedSize(customBtn->width(), customBtn->height()); 92         label->setText(QString::number(i+1)); 93         label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 94         label->move(45 + (i%4)*70 , 150 + (i/4)*70); 95         label->setAttribute(Qt::WA_TransparentForMouseEvents,true);  // 鼠标事件穿透 96     } 97 } 98  99 //-------------------------------------------------------------主窗口绘图事件绘制界面--------------------------------------------------------------//100 101 void ChooseCustoms::paintEvent(QPaintEvent *event)102 {103     QPainter painter(this);104     QPixmap pix;105     pix.load(":/res/海滩1.jpg");106     painter.drawPixmap(0, 0, this->width(), this->height(), pix);107 108     pix.load(":/res/Title.png");109     painter.drawPixmap((this->width() - pix.width())*0.5, 30, pix.width(), pix.height(), pix);110 }

翻金币页面代码:

1 #include "coinfligwidget.h"  2 #include "dataconfig.h"  3 #include "mybutton.h"  4 #include   5 #include   6 #include   7 #include   8 #include   9 #include  10 #include  11  12  13  14 CoinFligWidget::CoinFligWidget(int index) 15 { 16 //-------------------------------------------------------------初始化数据-------------------------------------------------------------------// 17     this->levalIndex = index; 18     dataConfig config; 19     for(int i = 0; i < 4; i++) 20     { 21         for(int j = 0; j < 4; j++) 22         { 23             gameArray[i][j] = config.mData[this->levalIndex][i][j]; 24         } 25     } 26 //-------------------------------------------------------------主窗口设置-------------------------------------------------------------------// 27     // 1.场景以及图标,标题设置 28     this->setFixedSize(360, 360*1.7); 29  30     this->setWindowIcon(QPixmap(":/res/Coin0001.png")); 31     this->setWindowTitle("翻金币"); 32  33     // 2.创建菜单栏,创建关闭按钮 34     QMenuBar *bar = this->menuBar(); 35     this->setMenuBar(bar); 36     QMenu *startMenu = bar->addMenu("开始"); 37     QAction *quickAction = startMenu->addAction("退出"); 38  39     connect(quickAction, &QAction::triggered, [=](){ 40         this->hide(); 41     }); 42  43     // 3.返回按钮,返回按钮发出的信号 44     MyButton *retBtn = new MyButton(":/res/BackButton.png", ":/res/BackButtonSelected.png"); 45     retBtn->setParent(this); 46     retBtn->move(this->width()-retBtn->width(), this->height()-retBtn->height()); 47  48     connect(retBtn, &MyButton::clicked, [=](){ 49         qDebug() << "点击了返回按钮"; 50         QSound *chooseSound = new QSound(":/res/TapButtonSound.wav", this); 51         chooseSound->play(); 52         QTimer::singleShot(400, this, [=](){  emit this->CoinFligBacksig(); }); 53     }); 54  55     // 4.显示当前关卡 56     QLabel *label = new QLabel(this); 57     QFont font; 58     font.setFamily("华文新魏"); 59     font.setPointSize(20); 60     label->setFont(font); 61     QString str = QString("Leavel: %1").arg(this->levalIndex); 62     label->setText(str); 63     label->setGeometry(QRect(20, this->height()-75, 120, 50)); 64  65     // 5.将胜利图片创建好,如果胜利触发了,将图片弹下去即可 66     QLabel *winLabel = new QLabel(this); 67     QPixmap temPix; 68     temPix.load(":/res/LevelCompletedDialogBg.png"); 69     winLabel->setGeometry(0, 0, temPix.width(), temPix.height()); 70     winLabel->setPixmap(temPix); 71     winLabel->move((this->width() - temPix.width())*0.5, -temPix.height()); 72  73     // 翻金币音效 74     QSound *flipSound = new QSound(":/res/ConFlipSound.wav",this); 75  76  77 //-------------------------------------------------------------金币初始化-------------------------------------------------------------------// 78     for(int i = 0; i < 4; i++) 79     { 80         for(int j = 0; j < 4; j++) 81         { 82             // 5.创建金币背景图片 83             QLabel *label = new QLabel(this); 84             label->setGeometry(0, 0, 50, 50); 85             label->setPixmap(QPixmap(":/res/BoardNode.png")); 86             label->move(80 + i*50, 200 + j*50); 87  88             // 6.初始化金币 89             QString img; 90             if(gameArray[i][j] == 1) 91             { 92                 img = ":/res/Coin0001.png"; 93             } 94             else 95             { 96                 img = ":/res/Coin0008.png"; 97             } 98  99             MyCoin *coin = new MyCoin(img);100             coin->setParent(this);101             coin->move(82 + i*50,203 + j*50);102 103             // 为每个金币属性赋值,1.记录坐标 2.记录正反104             coin->posX = i;105             coin->posY = j;106             coin->flag = gameArray[i][j];107             coinBtn[i][j] = coin;           108 109             // 7.监听每个按钮的点击110             connect(coin, &MyCoin::clicked, [=](){111                 flipSound->play();112 113                 // 在此颗金币点击的瞬间,其余金币全部禁用,鼠标拦截事件弹出114                 for(int i = 0; i < 4; i++)115                 {116                     for(int j = 0; j < 4; j++)117                     {118                         this->coinBtn[i][j]->isWin = true;119                     }120                 }121 122                 // 翻转金币123                 coin->changflag();124                 this->gameArray[i][j] = this->gameArray[i][j] == 0 ? 1 : 0;125 126 //-------------------------------------------------------------周围金币翻转,并且判断输赢-------------------------------------------------------//127                 QTimer::singleShot(300, this, [=](){128                     this->aroundChang(i, j, coin);129                     this->judgeWin(winLabel);130                 });131             });132         }133     }134 }135 136 // ->将周围金币进行翻转137 void CoinFligWidget::aroundChang(int i, int j, MyCoin *coin)138 {139     if(coin->posX+1 <= 3)140     {141         coinBtn[coin->posX+1][coin->posY]->changflag();142         gameArray[coin->posX+1][coin->posY] = gameArray[i][j] == 0 ? 1 : 0;143     }144     if(coin->posX-1 >= 0)145     {146         coinBtn[coin->posX-1][coin->posY]->changflag();147         gameArray[coin->posX-1][coin->posY] = gameArray[i][j] == 0 ? 1 : 0;148     }149     if(coin->posY+1 <= 3)150     {151         coinBtn[coin->posX][coin->posY+1]->changflag();152         gameArray[coin->posX][coin->posY+1] = gameArray[i][j] == 0 ? 1 : 0;153     }154     if(coin->posY-1 >= 0)155     {156         coinBtn[coin->posX][coin->posY-1]->changflag();157         gameArray[coin->posX][coin->posY-1] = gameArray[i][j] == 0 ? 1 : 0;158     }159 160     for(int i = 0; i < 4; i++)161     {162         for(int j = 0; j < 4; j++)163         {164             this->coinBtn[i][j]->isWin = false;165         }166     }167 }168 169 // ->判断是否胜利170 void CoinFligWidget::judgeWin(QLabel *label)171 {172     this->isWin = true;173     for(int i = 0; i < 4; i++)174     {175         for(int j = 0; j < 4; j++)176         {         177             if(this->coinBtn[i][j]->flag == false)178             {179                 this->isWin = false;180                 break;181             }          182         }183     }184 185     if(this->isWin)186     {187         qDebug() << "亲爱的,你的的确确是赢了!";188         // 胜利按钮音效189         QSound *winSound = new QSound(":/res/LevelWinSound.wav",this);190         winSound->play();191         QPropertyAnimation *animation = new QPropertyAnimation(label, "geometry");192         animation->setDuration(1000);193         animation->setStartValue(QRect(label->x(), label->y(), label->width(), label->height()));194         animation->setEndValue(QRect(label->x(), label->y()+144, label->width(), label->height()));195         animation->setEasingCurve(QEasingCurve::OutBounce);196         animation->start();197 198         // 赢了之后禁止翻转按钮199         for(int i = 0; i < 4; i++)200         {201             for(int j = 0; j < 4; j++)202             {203                 this->coinBtn[i][j]->isWin = true;204             }205         }206     }   207 }208 209 //-------------------------------------------------------------主窗口绘图事件绘制界面--------------------------------------------------------------//210 void CoinFligWidget::paintEvent(QPaintEvent *event)211 {212     QPainter painter(this);213     QPixmap pix;214 215     // 加载背景216     pix.load(":/res/海滩.jpg");217     painter.drawPixmap(QRect(0, 0, this->width(), this->height()), pix);218 219     // 加载标题220     pix.load(":/res/Title.png");221     pix = pix.scaled(pix.width()*0.5, pix.height()*0.5);222     painter.drawPixmap(10,30,pix.width(),pix.height(),pix);223 }

-总结-

  • 这一次项目让我有了对C++的重新审视,刚学的时候:哟,这不就是C嘛,中途:WOC,这是什么??? 做完项目:原来这就是C++啊<仍然懵。。。>
  • 要想开启一个项目,一定是先主体后局部,先框架后函数,以前我写代码总是热衷于函数某一个功能的优化,导致项目迟迟难以推进,这次真正见识到了,先搭框架后细化的感觉有多爽。
  • Qt的环境变量花了我大量时间配置......

关键词: 关闭按钮 标题设置