Qt项目-翻金币游戏
Posted 北極星
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt项目-翻金币游戏相关的知识,希望对你有一定的参考价值。
Qt基础课程完结项目,完成一款小游戏并封装:翻金币游戏,通过点击金币进行翻面,让所有金币为同一面就游戏通过进入下一关。
过程中会使用前面学到的 “信号和槽”,“Qt图片资源显示”,“Qt播放音频”,“Qt绘图函数”,“Qt消息控件”等等知识。是一次前面所学知识的汇总。
框架如下,(因为这个项目完成有些时间了,现在才记录下来,流程部分是看的当时的程序注释,有些不明白的地方可以私信我)
运行平台:
主界面代码:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QPainter> #include <QMenuBar> #include <QDebug> #include <QSound> #include <QTimer> #include "mybutton.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) ui->setupUi(this); //-------------------------------------------------------------主窗口设置-------------------------------------------------------------------// // 1.主窗口场景设置 this->setFixedSize(360, 360*1.7); this->setWindowIcon(QPixmap(":/res/Coin0001.png")); this->setWindowTitle("翻金币"); // 2.主窗口控件设置 connect(ui->actionExit, &QAction::triggered, [=]() this->close(); ); // 3.创建关卡选择界面指针对象,同时监听关卡按钮前线发回的信号 this->CustomWidget = new ChooseCustoms; connect(CustomWidget, &ChooseCustoms::ChooseCustomBacksig, [=]() this->setGeometry(CustomWidget->geometry()); CustomWidget->hide(); this->show(); ); // 4.创建并移动开始按钮对象 MyButton *startBtn = new MyButton(":/res/MenuSceneStartButton.png"); startBtn->setParent(this); startBtn->move((this->width() - startBtn->width())*0.5, this->height()*0.7); // 5.播放开始按钮点击音效 QSound *startSound = new QSound(":/res/TapButtonSound.wav", this); connect(startBtn, &MyButton::clicked, [=]() qDebug() << "点击了开始按钮"; startBtn->jumpDown(); startSound->play(); startBtn->jumpUp(); QTimer::singleShot(400, this, [=]() this->hide(); CustomWidget->show(); ); ); //-------------------------------------------------------------主窗口绘图事件绘制界面-------------------------------------------------------------------// void MainWindow::paintEvent(QPaintEvent *) QPainter painter(this); // 绘制主场景背景界面 QPixmap pix; pix.load(":/res/海滩.jpg"); painter.drawPixmap(QRect(0, 0, this->width(), this->height()), pix); // 绘制主场景图标 pix.load(":/res/Title.png"); pix = pix.scaled(pix.width()*0.7, pix.height()*0.7); painter.drawPixmap(10, 30, pix.width(), pix.height() , pix); MainWindow::~MainWindow() delete ui;
关卡选择界面函数:
#include "choosecustoms.h" #include <QMenuBar> #include <QPainter> #include <QSound> #include <QLabel> #include <QTimer> #include <QDebug> ChooseCustoms::ChooseCustoms(QWidget *parent) : QMainWindow(parent) //-------------------------------------------------------------主窗口设置-------------------------------------------------------------------// // 1.场景以及图标,标题设置 this->setFixedSize(360, 360*1.7); this->setWindowIcon(QPixmap(":/res/Coin0001.png")); this->setWindowTitle("翻金币"); // 2.创建菜单栏,创建关闭按钮 QMenuBar *bar = this->menuBar(); this->setMenuBar(bar); QMenu *startMenu = bar->addMenu("开始"); QAction *quitAction = startMenu->addAction("退出"); connect(quitAction, &QAction::triggered, [=]() this->hide(); ); // 3.返回按钮,返回按钮点击后返回的信号 MyButton *retBtn = new MyButton(":/res/BackButton.png", ":/res/BackButtonSelected.png"); retBtn->setParent(this); retBtn->move(this->width()-retBtn->width(), this->height()-retBtn->height()); connect(retBtn, &MyButton::clicked, [=]() qDebug() << "点击了返回按钮"; QSound *retSound = new QSound(":/res/BackButtonSound.wav", this); retSound->play(); QTimer::singleShot(400, this, [=]() emit this->ChooseCustomBacksig(); ); ); //-------------------------------------------------------------for循环创建关卡选择按钮----------------------------------------------------------// // 4.创建关卡选择按钮 for(int i = 0; i < 20; i++) // 绘制按钮图标 MyButton *customBtn = new MyButton(":/res/LevelIcon.png"); customBtn->setParent(this); customBtn->move(45 + (i%4)*70 , 150 + (i/4)*70); // 我们要一个4x5的矩阵 customBtnArray[i] = customBtn; // 关联每一个按钮的启动函数 connect(customBtn, &MyButton::clicked, [=]() // 关卡选择按钮上锁,其余的按钮不能点击 for(int i = 0; i < 20; i++) customBtnArray[i]->isclick = true; qDebug() << "选择了" << i+1 << "关卡"; if(this->coinfligwidget == NULL) customBtn->jumpDown(); customBtn->jumpUp(); QSound *chooseSound = new QSound(":/res/TapButtonSound.wav", this); chooseSound->play(); QTimer::singleShot(400, this, [=]() this->hide(); this->coinfligwidget = new CoinFligWidget(i+1); coinfligwidget->setGeometry(this->geometry()); coinfligwidget->show(); // 关卡选择按钮解锁,其余的按钮可以点击 for(int i = 0; i < 20; i++) customBtnArray[i]->isclick = false; connect(coinfligwidget, &CoinFligWidget::CoinFligBacksig, [=]() this->setGeometry(coinfligwidget->geometry()); this->show(); delete coinfligwidget; coinfligwidget = NULL; ); ); ); // 绘制按钮数字 QLabel *label = new QLabel; label->setParent(this); label->setFixedSize(customBtn->width(), customBtn->height()); label->setText(QString::number(i+1)); label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); label->move(45 + (i%4)*70 , 150 + (i/4)*70); label->setAttribute(Qt::WA_TransparentForMouseEvents,true); // 鼠标事件穿透 //-------------------------------------------------------------主窗口绘图事件绘制界面--------------------------------------------------------------// void ChooseCustoms::paintEvent(QPaintEvent *event) QPainter painter(this); QPixmap pix; pix.load(":/res/海滩1.jpg"); painter.drawPixmap(0, 0, this->width(), this->height(), pix); pix.load(":/res/Title.png"); painter.drawPixmap((this->width() - pix.width())*0.5, 30, pix.width(), pix.height(), pix);
翻金币页面代码:
#include "coinfligwidget.h" #include "dataconfig.h" #include "mybutton.h" #include <QPropertyAnimation> #include <QMenuBar> #include <iostream> #include <QPainter> #include <QDebug> #include <QSound> #include <QTimer> CoinFligWidget::CoinFligWidget(int index) //-------------------------------------------------------------初始化数据-------------------------------------------------------------------// this->levalIndex = index; dataConfig config; for(int i = 0; i < 4; i++) for(int j = 0; j < 4; j++) gameArray[i][j] = config.mData[this->levalIndex][i][j]; //-------------------------------------------------------------主窗口设置-------------------------------------------------------------------// // 1.场景以及图标,标题设置 this->setFixedSize(360, 360*1.7); this->setWindowIcon(QPixmap(":/res/Coin0001.png")); this->setWindowTitle("翻金币"); // 2.创建菜单栏,创建关闭按钮 QMenuBar *bar = this->menuBar(); this->setMenuBar(bar); QMenu *startMenu = bar->addMenu("开始"); QAction *quickAction = startMenu->addAction("退出"); connect(quickAction, &QAction::triggered, [=]() this->hide(); ); // 3.返回按钮,返回按钮发出的信号 MyButton *retBtn = new MyButton(":/res/BackButton.png", ":/res/BackButtonSelected.png"); retBtn->setParent(this); retBtn->move(this->width()-retBtn->width(), this->height()-retBtn->height()); connect(retBtn, &MyButton::clicked, [=]() qDebug() << "点击了返回按钮"; QSound *chooseSound = new QSound(":/res/TapButtonSound.wav", this); chooseSound->play(); QTimer::singleShot(400, this, [=]() emit this->CoinFligBacksig(); ); ); // 4.显示当前关卡 QLabel *label = new QLabel(this); QFont font; font.setFamily("华文新魏"); font.setPointSize(20); label->setFont(font); QString str = QString("Leavel: %1").arg(this->levalIndex); label->setText(str); label->setGeometry(QRect(20, this->height()-75, 120, 50)); // 5.将胜利图片创建好,如果胜利触发了,将图片弹下去即可 QLabel *winLabel = new QLabel(this); QPixmap temPix; temPix.load(":/res/LevelCompletedDialogBg.png"); winLabel->setGeometry(0, 0, temPix.width(), temPix.height()); winLabel->setPixmap(temPix); winLabel->move((this->width() - temPix.width())*0.5, -temPix.height()); // 翻金币音效 QSound *flipSound = new QSound(":/res/ConFlipSound.wav",this); //-------------------------------------------------------------金币初始化-------------------------------------------------------------------// for(int i = 0; i < 4; i++) for(int j = 0; j < 4; j++) // 5.创建金币背景图片 QLabel *label = new QLabel(this); label->setGeometry(0, 0, 50, 50); label->setPixmap(QPixmap(":/res/BoardNode.png")); label->move(80 + i*50, 200 + j*50); // 6.初始化金币 QString img; if(gameArray[i][j] == 1) img = ":/res/Coin0001.png"; else img = ":/res/Coin0008.png"; MyCoin *coin = new MyCoin(img); coin->setParent(this); coin->move(82 + i*50,203 + j*50); // 为每个金币属性赋值,1.记录坐标 2.记录正反 coin->posX = i; coin->posY = j; coin->flag = gameArray[i][j]; coinBtn[i][j] = coin; // 7.监听每个按钮的点击 connect(coin, &MyCoin::clicked, [=]() flipSound->play(); // 在此颗金币点击的瞬间,其余金币全部禁用,鼠标拦截事件弹出 for(int i = 0; i < 4; i++) for(int j = 0; j < 4; j++) this->coinBtn[i][j]->isWin = true; // 翻转金币 coin->changflag(); this->gameArray[i][j] = this->gameArray[i][j] == 0 ? 1 : 0; //-------------------------------------------------------------周围金币翻转,并且判断输赢-------------------------------------------------------// QTimer::singleShot(300, this, [=]() this->aroundChang(i, j, coin); this->judgeWin(winLabel); ); ); // ->将周围金币进行翻转 void CoinFligWidget::aroundChang(int i, int j, MyCoin *coin) if(coin->posX+1 <= 3) coinBtn[coin->posX+1][coin->posY]->changflag(); gameArray[coin->posX+1][coin->posY] = gameArray[i][j] == 0 ? 1 : 0; if(coin->posX-1 >= 0) coinBtn[coin->posX-1][coin->posY]->changflag(); gameArray[coin->posX-1][coin->posY] = gameArray[i][j] == 0 ? 1 : 0; if(coin->posY+1 <= 3) coinBtn[coin->posX][coin->posY+1]->changflag(); gameArray[coin->posX][coin->posY+1] = gameArray[i][j] == 0 ? 1 : 0; if(coin->posY-1 >= 0) coinBtn[coin->posX][coin->posY-1]->changflag(); gameArray[coin->posX][coin->posY-1] = gameArray[i][j] == 0 ? 1 : 0; for(int i = 0; i < 4; i++) for(int j = 0; j < 4; j++) this->coinBtn[i][j]->isWin = false; // ->判断是否胜利 void CoinFligWidget::judgeWin(QLabel *label) this->isWin = true; for(int i = 0; i < 4; i++) for(int j = 0; j < 4; j++) if(this->coinBtn[i][j]->flag == false) this->isWin = false; break; if(this->isWin) qDebug() << "亲爱的,你的的确确是赢了!"; // 胜利按钮音效 QSound *winSound = new QSound(":/res/LevelWinSound.wav",this); winSound->play(); QPropertyAnimation *animation = new QPropertyAnimation(label, "geometry"); animation->setDuration(1000); animation->setStartValue(QRect(label->x(), label->y(), label->width(), label->height())); animation->setEndValue(QRect(label->x(), label->y()+144, label->width(), label->height())); animation->setEasingCurve(QEasingCurve::OutBounce); animation->start(); // 赢了之后禁止翻转按钮 for(int i = 0; i < 4; i++) for(int j = 0; j < 4; j++) this->coinBtn[i][j]->isWin = true; //-------------------------------------------------------------主窗口绘图事件绘制界面--------------------------------------------------------------// void CoinFligWidget::paintEvent(QPaintEvent *event) QPainter painter(this); QPixmap pix; // 加载背景 pix.load(":/res/海滩.jpg"); painter.drawPixmap(QRect(0, 0, this->width(), this->height()), pix); // 加载标题 pix.load(":/res/Title.png"); pix = pix.scaled(pix.width()*0.5, pix.height()*0.5); painter.drawPixmap(10,30,pix.width(),pix.height(),pix);
- 这一次项目让我有了对C++的重新审视,刚学的时候:哟,这不就是C嘛,中途:WOC,这是什么??? 做完项目:原来这就是C++啊<仍然懵。。。>
- 要想开启一个项目,一定是先主体后局部,先框架后函数,以前我写代码总是热衷于函数某一个功能的优化,导致项目迟迟难以推进,这次真正见识到了,先搭框架后细化的感觉有多爽。
- Qt的环境变量花了我大量时间配置......
以上是关于Qt项目-翻金币游戏的主要内容,如果未能解决你的问题,请参考以下文章
新星计划python赛道pygame让你一步步实现翻牌游戏(金币旋转大头贴等),打造更有趣的新星之旅
新星计划python赛道pygame让你一步步实现翻牌游戏(金币旋转大头贴等),打造更有趣的新星之旅