【QT】翻金币项目

代码资源:https://download.csdn.net/download/qq_36926037/85106594

1 项目基本配置

1.1 创建项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2 添加资源文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2 主场景

2.1 设置游戏主场景配置

在这里插入图片描述
在这里插入图片描述

#include "mainscene.h"
#include "ui_mainscene.h"

MainScene::MainScene(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainScene)
{
    ui->setupUi(this);
    //(1)配置主场景
    //设置固定大小
    setFixedSize(320,588);
    //设置窗口图标
    setWindowIcon(QIcon(":/res/Coin0001.png"));
    //设置标题
    setWindowTitle(" 翻金币主场景");
    //退出菜单项实现
    connect(ui->actionquit,&QAction::triggered,[=]()
    {
       this->close();
    });
}

MainScene::~MainScene()
{
    delete ui;
}


在这里插入图片描述

2.2 设置主场景背景图片

思路:重写paintEvent事件,并添加代码,绘制背景图片
(1)paintEvent事件声明:在mainscene.h中声明绘图事件

#ifndef MAINSCENE_H
#define MAINSCENE_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainScene; }
QT_END_NAMESPACE

class MainScene : public QMainWindow
{
    Q_OBJECT

public:
    MainScene(QWidget *parent = nullptr);
    ~MainScene();
    //绘图事件声明
    void paintEvent(QPaintEvent *ev);

private:
    Ui::MainScene *ui;
};
#endif // MAINSCENE_H

在这里插入图片描述
(2)绘图事件实现:在mainscene.cpp中实现绘图事件

//绘图事件实现
#include <QPainter>
void MainScene::paintEvent(QPaintEvent *ev)
{
    //(1)画家
    QPainter painter(this);
    //(2)绘图设备,绘图
    QPixmap pix;
    pix.load(":/res/PlayLevelSceneBg.png");
    //(3)绘图
    //3.1 绘制背景
    painter.drawPixmap(0,0,
                       this->width(),this->height(),
                       pix);//将图片设置为窗口大小绘制

    //3.2 绘制背景上的图标
    pix.load(":/res/Title.png");
    pix=pix.scaled(pix.width()*0.5,pix.height()*0.5);//缩放
    painter.drawPixmap(10,30,pix);

}

在这里插入图片描述

2.3 创建开始按钮

需求分析: 开始按钮点击后,有弹跳的效果,这个效果我们利用自定义控件来实现,自己封装一个按钮来实现这个效果。
(1)创建MyPushbutton类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
(2)修改MyPushbutton类的基类为QPushButton
在这里插入图片描述
在这里插入图片描述
(3)修改MyPushbutton类的构造函数,及构造函数的实现

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

#include <QPushButton>

class MyPushButton : public QPushButton
{
    Q_OBJECT
public:
    
//    explicit MyPushButton(QWidget *parent = nullptr);
    //修改构造函数:参数1正常显示的图片路径, 参数2:按下后显示的图片路径
    MyPushButton(QString normalImg,QString pressImg="");
    QString nomalImgPath;//保存用户传入的默认图片显示路径
    QString pressImgPath;//保存用户按下后显示的图片路径

signals:

};

#endif // MYPUSHBUTTON_H

在这里插入图片描述

#include "mypushbutton.h"

//MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
//{
//}

#include <QPixmap>
#include <QDebug>
 MyPushButton::MyPushButton(QString normalImg,QString pressImg)
 {
     this->nomalImgPath=normalImg;
     this->pressImgPath=pressImg;
     
     //(1)加载正常状态下的图片
     QPixmap pix;
     bool ret=pix.load(normalImg);
     if(!ret)
     {
         qDebug()<<"图片加载失败";
         return;
     }
     //(2)设置正常状态下图片的固定大小
     this->setFixedSize(pix.width(),pix.height());
     //(3)设置不规则图片样式
     this->setStyleSheet("QPushButton{border:0pix;}");
     //(4)设置图标,及大小
     this->setIcon(pix);
     this->setIconSize(QSize(pix.width(),pix.height()));   
 }

在这里插入图片描述
(4)开始按钮实现:在mainscene.cpp中使用自定义的mypushbutton控件

MainScene::MainScene(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainScene)
{
    ui->setupUi(this);
    //(1)配置主场景
    //设置固定大小
    setFixedSize(320,588);
    //设置窗口图标
    setWindowIcon(QIcon(":/res/Coin0001.png"));
    //设置标题
    setWindowTitle(" 翻金币主场景");
    //退出菜单项实现
    connect(ui->actionquit,&QAction::triggered,[=]()
    {
       this->close();
    });

    //(2)开始按钮
    //#include "mypushbutton.h"
    MyPushButton *startBtn=new MyPushButton(":/res/MenuSceneStartButton.png");
    startBtn->setParent(this);
    startBtn->move(this->width()*0.5-startBtn->width()*0.5,this->height()*0.7);
    connect(startBtn,&MyPushButton::clicked,[=]()
    {
        qDebug()<<"点击按钮";
    });
}

在这里插入图片描述

2.4 开始按钮跳跃效果实现

(1)MyPushButton.h中声明弹跳特效

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

#include <QPushButton>

class MyPushButton : public QPushButton
{
    Q_OBJECT
public:

//    explicit MyPushButton(QWidget *parent = nullptr);
    //修改构造函数:参数1正常显示的图片路径, 参数2:按下后显示的图片路径
    MyPushButton(QString normalImg,QString pressImg="");
    QString nomalImgPath;//保存用户传入的默认图片显示路径
    QString pressImgPath;//保存用户按下后显示的图片路径
    
    //弹跳特效
    void zoom1();//向下跳
    void zoom2();//向上跳

signals:

};

#endif // MYPUSHBUTTON_H

在这里插入图片描述
(2)MyPushButton.cpp中实现弹跳特效

//向下跳
 #include <QPropertyAnimation>//动画特效
 void MyPushButton::zoom1()
 {
     //(1)创建动态对象
     QPropertyAnimation *animal=new QPropertyAnimation(this,"geometry");
     //(2)设置动画时间间隔
     animal->setDuration(200);
     //(3)设置起始位置,结束位置
     animal->setStartValue(QRect(this->x(),this->y(),this->width(),this->height()));
     animal->setEndValue(QRect(this->x(),this->y()+10,this->width(),this->height()));
     //(4)设置弹跳曲线
     animal->setEasingCurve(QEasingCurve::OutBounce);
     //(5)执行动画
     animal->start();
 }
 void MyPushButton::zoom2()
 {
     //(1)创建动态对象
     QPropertyAnimation *animal=new QPropertyAnimation(this,"geometry");
     //(2)设置动画时间间隔
     animal->setDuration(200);
     //(3)设置起始位置,结束位置
     animal->setStartValue(QRect(this->x(),this->y()+10,this->width(),this->height()));
     animal->setEndValue(QRect(this->x(),this->y(),this->width(),this->height()));
     //(4)设置弹跳曲线
     animal->setEasingCurve(QEasingCurve::OutBounce);
     //(5)执行动画
     animal->start();
 }//向上跳

在这里插入图片描述

(3)mainscene.cpp中使用弹跳特效

MainScene::MainScene(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainScene)
{
    ui->setupUi(this);
    //(1)配置主场景
    //设置固定大小
    setFixedSize(320,588);
    //设置窗口图标
    setWindowIcon(QIcon(":/res/Coin0001.png"));
    //设置标题
    setWindowTitle(" 翻金币主场景");
    //退出菜单项实现
    connect(ui->actionquit,&QAction::triggered,[=]()
    {
       this->close();
    });

    //(2)开始按钮
    //#include "mypushbutton.h"
    MyPushButton *startBtn=new MyPushButton(":/res/MenuSceneStartButton.png");
    startBtn->setParent(this);
    startBtn->move(this->width()*0.5-startBtn->width()*0.5,
                   this->height()*0.7);
    connect(startBtn,&MyPushButton::clicked,[=]()
    {
        qDebug()<<"点击按钮";
        //弹跳特效
        startBtn->zoom1();
        startBtn->zoom2();
    });
}

在这里插入图片描述

2.5 创建选择关卡场景

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.6 点击按钮进入选择关卡场景

(1)在mainscene.h中声明选择关卡场景

#ifndef MAINSCENE_H
#define MAINSCENE_H

#include <QMainWindow>
#include "chooselevelscene.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainScene; }
QT_END_NAMESPACE

class MainScene : public QMainWindow
{
    Q_OBJECT

public:
    MainScene(QWidget *parent = nullptr);
    ~MainScene();
    //绘图事件声明
    void paintEvent(QPaintEvent *ev);
    
    //创建选择关卡场景
    ChooseLevelScene *chooseScene=NULL;


private:
    Ui::MainScene *ui;
};
#endif // MAINSCENE_H

在这里插入图片描述
(2)实例化进入关卡场景,并通过点击开始按钮,进入该场景:在mainscene.cpp中实现

MainScene::MainScene(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainScene)
{
    ui->setupUi(this);
    //(1)配置主场景
    //设置固定大小
    setFixedSize(320,588);
    //设置窗口图标
    setWindowIcon(QIcon(":/res/Coin0001.png"));
    //设置标题
    setWindowTitle(" 翻金币主场景");
    //退出菜单项实现
    connect(ui->actionquit,&QAction::triggered,[=]()
    {
       this->close();
    });

    //(2)开始按钮
    //#include "mypushbutton.h"
    MyPushButton *startBtn=new MyPushButton(":/res/MenuSceneStartButton.png");
    startBtn->setParent(this);
    startBtn->move(this->width()*0.5-startBtn->width()*0.5,
                   this->height()*0.7);

    chooseScene =new ChooseLevelScene;//实例化选择关卡场景
    connect(startBtn,&MyPushButton::clicked,[=]()
    {
        //弹跳特效
        startBtn->zoom1();
        startBtn->zoom2();
        //进入选择关卡场景
        QTimer::singleShot(500,this,[=]()
        {
            this->hide();//当前窗口隐藏
            chooseScene->show();//显示选择关卡场景
        });//延时进入
    });
}

在这里插入图片描述

3 选择关卡场景

3.1 场景关卡基本配置

目标: 配置选择关卡场景菜单栏,窗口大小,窗口标题,窗口图标

#include "chooselevelscene.h"
#include <QMenuBar>
#include <QMenu>

ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
    //配置选择关卡场景
    //(1)设置场景界面大小
    this->setFixedSize(320,588);
    //(2)设置图标
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    //(3)设置标题
    this->setWindowTitle("选择关卡场景");
    //(4)创建菜单栏   #include <QMenuBar>
    QMenuBar *bar=menuBar();
    setMenuBar(bar);
    //(5)创建开始菜单 #include <QMenu>
    QMenu *startMenu=bar->addMenu("开始");
    //(6)创建菜单项
    QAction *quitAction=startMenu->addAction("退出");
    //(7)点击退出,实现退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });
}

在这里插入图片描述

3.2 设置选择关卡场景背景图片

(1)绘图事件声明

#ifndef CHOOSELEVELSCENE_H
#define CHOOSELEVELSCENE_H

#include <QMainWindow>

class ChooseLevelScene : public QMainWindow
{
    Q_OBJECT
public:
    explicit ChooseLevelScene(QWidget *parent = nullptr);
    
    //选择关卡场景背景,绘图事件
    void paintEvent(QPaintEvent *ev);

signals:

};
#endif // CHOOSELEVELSCENE_H

在这里插入图片描述
(2)绘图事件实现

#include <QPainter>
#include <QPixmap>
void ChooseLevelScene:: paintEvent(QPaintEvent *ev)
{
    //绘制背景图片
    //(1)声明画家
    QPainter painter(this);
    //(2)声明设备
    QPixmap pix;
    pix.load(":/res/OtherSceneBg.png");
    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);

}

在这里插入图片描述

3.3 返回按钮的图片切换

重写void mousePressEvent()实现和void mouseReleaseEvent()事件。不同的事件下,自定义按钮显示不同的icon图片
(1)按钮按下和释放事件的声明:mypushbutton.h中声明

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

#include <QPushButton>

class MyPushButton : public QPushButton
{
    Q_OBJECT
public:

//    explicit MyPushButton(QWidget *parent = nullptr);
    //修改构造函数:参数1正常显示的图片路径, 参数2:按下后显示的图片路径
    MyPushButton(QString normalImg,QString pressImg="");
    QString nomalImgPath;//保存用户传入的默认图片显示路径
    QString pressImgPath;//保存用户按下后显示的图片路径

    //弹跳特效
    void zoom1();//向下跳
    void zoom2();//向上跳
    
    //鼠标点击和释放事件声明
    void mousePressEvent(QMouseEvent *ev);
    void mouseReleaseEvent(QMouseEvent *ev);
signals:
};

#endif // MYPUSHBUTTON_H

在这里插入图片描述
(2)按钮按下和释放事件的实现:mypushbutton.cpp中实现

 void MyPushButton::mousePressEvent(QMouseEvent *ev)
{
     if(this->pressImgPath!=NULL)//按下图片不为空,则需要切换图片
     {
         QPixmap pix;
         bool ret=pix.load(pressImgPath);
         if(!ret)
         {
             qDebug()<<"图片加载失败";
             return;
         }
         //设置图片的固定大小
         this->setFixedSize(pix.width(),pix.height());
         //设置不规则图片样式
         this->setStyleSheet("QPushButton{border:0pix;}");
         //设置图标,及大小
         this->setIcon(pix);
         this->setIconSize(QSize(pix.width(),pix.height()));
     }
     // 让父类执行其他操作
     return QPushButton::mousePressEvent(ev);//不添加该步骤,无法实现按钮的其他操作
}
void MyPushButton:: mouseReleaseEvent(QMouseEvent *ev)
{
    if(this->pressImgPath!=NULL)//按下图片不为空,则需要切换图片
    {
        QPixmap pix;
        bool ret=pix.load(this->nomalImgPath);
        if(!ret)
        {
            qDebug()<<"图片加载失败";
            return;
        }
        //设置图片的固定大小
        this->setFixedSize(pix.width(),pix.height());
        //设置不规则图片样式
        this->setStyleSheet("QPushButton{border:0pix;}");
        //设置图标,及大小
        this->setIcon(pix);
        this->setIconSize(QSize(pix.width(),pix.height()));
    }
    // 让父类执行其他操作
    return QPushButton:: mouseReleaseEvent(ev);//不添加该步骤,无法实现按钮的其他操作
}

在这里插入图片描述

3.4 点击返回按钮切换至主场景

首先点击选择关卡场景中返回按钮,发送一个自定义信号;主场景中监听自定义信号,收到自定义信号后,隐藏选择关卡场景,显示主场景。
(1)在选择关卡场景中自定义信号:在chooselevelsecne.h中声明信号,告诉主场景点击了返回
在这里插入图片描述
(2)在选择关卡场景中设置点击按钮,发送信号:chooselevelscene.cpp实现,点击返回按钮发送信号。emit this->ChooseSceneBack();

ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
    //配置选择关卡场景
    //(1)设置场景界面大小
    this->setFixedSize(320,588);
    //(2)设置图标
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    //(3)设置标题
    this->setWindowTitle("选择关卡场景");
    //(4)创建菜单栏   #include <QMenuBar>
    QMenuBar *bar=menuBar();
    setMenuBar(bar);
    //(5)创建开始菜单 #include <QMenu>
    QMenu *startMenu=bar->addMenu("开始");
    //(6)创建菜单项
    QAction *quitAction=startMenu->addAction("退出");
    //(7)点击退出,实现退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });

    //返回按钮
    //#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    //(2)点击返回,切换至主场景
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });
}

在这里插入图片描述
(3)在主场景中,监听返回关卡场景的发送的信号:mainscene.cpp中监听信号

MainScene::MainScene(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainScene)
{
    ui->setupUi(this);
    //(1)配置主场景
    //设置固定大小
    setFixedSize(320,588);
    //设置窗口图标
    setWindowIcon(QIcon(":/res/Coin0001.png"));
    //设置标题
    setWindowTitle(" 翻金币主场景");
    //退出菜单项实现
    connect(ui->actionquit,&QAction::triggered,[=]()
    {
       this->close();
    });

    //(2)开始按钮,跳转到选择关卡场景
    //#include "mypushbutton.h"
    MyPushButton *startBtn=new MyPushButton(":/res/MenuSceneStartButton.png");
    startBtn->setParent(this);
    startBtn->move(this->width()*0.5-startBtn->width()*0.5,
                   this->height()*0.7);

    chooseScene =new ChooseLevelScene;//实例化选择关卡场景
    connect(startBtn,&MyPushButton::clicked,[=]()
    {
        //弹跳特效
        startBtn->zoom1();
        startBtn->zoom2();
        //进入选择关卡场景
        QTimer::singleShot(500,this,[=]()
        {
            this->hide();//当前窗口隐藏
            chooseScene->show();//显示选择关卡场景   
        });//延时进入
    });
    
    //(3)监听选择关卡场景的信号#include <chooselevelscene.h>
    connect(chooseScene,&ChooseLevelScene::ChooseSceneBack,[=]()
    {
        chooseScene->hide();
        this->show();
    });
}

在这里插入图片描述

3.5 选择关卡场景关卡按钮创建

ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
    //1.配置选择关卡场景
    //(1)设置场景界面大小
    this->setFixedSize(320,588);
    //(2)设置图标
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    //(3)设置标题
    this->setWindowTitle("选择关卡场景");
    //(4)创建菜单栏   #include <QMenuBar>
    QMenuBar *bar=menuBar();
    setMenuBar(bar);
    //(5)创建开始菜单 #include <QMenu>
    QMenu *startMenu=bar->addMenu("开始");
    //(6)创建菜单项
    QAction *quitAction=startMenu->addAction("退出");
    //(7)点击退出,实现退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });


    //2.返回按钮
    //#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    //(2)点击返回,切换至主场景
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });

    //3.创建选择关卡的按钮
    for (int i=0;i<20;i++)
    {
        //自定义按钮:构造函数包含两个参数
        MyPushButton *menuBtn=new MyPushButton(":/res/LevelIcon.png");
        menuBtn->setParent(this);
        menuBtn->move(i%4*70+25,i/4*70+100);

        //设置文字标签
        QLabel *label=new QLabel;
        label->setParent(this);
        label->setFixedSize(menuBtn->width(),menuBtn->height());
        label->setText(QString::number(i+1));//标签上的文字
        label->move(i%4*70+25,i/4*70+100);
        label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//文字水平和垂直居中
        //设置让鼠标进行穿透,否者label覆盖按钮,不能执行操作
        label->setAttribute(Qt::WA_TransparentForMouseEvents);
    }
}

在这里插入图片描述

3.6 创建翻金币场景

(1)创建翻金币场景.h和.cpp文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(2)修改翻金币场景的构造函数:playscene.h/.cpp构造函数修改

#ifndef PLAYSCENE_H
#define PLAYSCENE_H

#include <QMainWindow>

class PlayScene : public QMainWindow
{
    Q_OBJECT
public:
//    explicit PlayScene(QWidget *parent = nullptr);
    PlayScene(int levelNum);
    int levelIndex;//内部成员,记录所选的关卡

signals:

};

#endif // PLAYSCENE_H

在这里插入图片描述

#include "playscene.h"

//PlayScene::PlayScene(QWidget *parent) : QMainWindow(parent)
//{

//}
#include <QDebug>
PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;
}

在这里插入图片描述

3.7 点击关卡按钮进入翻金币场景

(1)在选择关卡场景中引入翻金币场景:chooselevelscene.cpp
在这里插入图片描述
(2)选择关卡场景中,通过点击选择关卡按钮进入相应的翻金币场景:ChooseLevelScene.cpp

ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
    //1.配置选择关卡场景
    //(1)设置场景界面大小
    this->setFixedSize(320,588);
    //(2)设置图标
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    //(3)设置标题
    this->setWindowTitle("选择关卡场景");
    //(4)创建菜单栏   #include <QMenuBar>
    QMenuBar *bar=menuBar();
    setMenuBar(bar);
    //(5)创建开始菜单 #include <QMenu>
    QMenu *startMenu=bar->addMenu("开始");
    //(6)创建菜单项
    QAction *quitAction=startMenu->addAction("退出");
    //(7)点击退出,实现退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });


    //2.返回按钮
    //#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    //(2)点击返回,切换至主场景
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });

    //3.创建选择关卡的按钮
    for (int i=0;i<20;i++)
    {
        //自定义按钮:构造函数包含两个参数
        MyPushButton *menuBtn=new MyPushButton(":/res/LevelIcon.png");
        menuBtn->setParent(this);
        menuBtn->move(i%4*70+25,i/4*70+100);

        //设置文字标签
        QLabel *label=new QLabel;
        label->setParent(this);
        label->setFixedSize(menuBtn->width(),menuBtn->height());
        label->setText(QString::number(i+1));//标签上的文字
        label->move(i%4*70+25,i/4*70+100);
        label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//文字水平和垂直居中
        //设置让鼠标进行穿透,否者label覆盖按钮,不能执行操作
        label->setAttribute(Qt::WA_TransparentForMouseEvents);

        //监听每个按钮的点击事件
        connect(menuBtn,&QPushButton::clicked,[=]()
        {
           //#include "playscene.h"
           this->hide();//隐藏选择关卡场景
           this->play=new PlayScene(i+1);//创建翻金币场景
           play->show();//显示翻金币场景
        });
    }
}

在这里插入图片描述

4 翻金币场景

4.1 翻金币场景基本配置

#include "playscene.h"

//PlayScene::PlayScene(QWidget *parent) : QMainWindow(parent)
//{

//}
#include <QDebug>
#include <QMenuBar>
PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });
}

在这里插入图片描述

4.2 翻金币场景背景图片

(1)声明绘图事件:palyscene.h

#ifndef PLAYSCENE_H
#define PLAYSCENE_H

#include <QMainWindow>

class PlayScene : public QMainWindow
{
    Q_OBJECT
public:
//    explicit PlayScene(QWidget *parent = nullptr);
    PlayScene(int levelNum);
    int levelIndex;//内部成员,记录所选的关卡
    
    //重写绘图事件
    void paintEvent(QPaintEvent *ev);

signals:

};

#endif // PLAYSCENE_H

在这里插入图片描述
(2)实现绘图事件:playscene.cpp

//重写绘图事件
#include <QPainter>
#include <QPixmap>
void PlayScene:: paintEvent(QPaintEvent *ev)
{
    //加载背景
    QPainter painter(this);
    QPixmap pix;
    pix.load(":/res/PlayLevelSceneBg.png");
    painter.drawPixmap(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);

}

在这里插入图片描述

4.3 翻金币场景返回按钮

(1)声明返回按钮的信号:palyscene.h

#ifndef PLAYSCENE_H
#define PLAYSCENE_H

#include <QMainWindow>

class PlayScene : public QMainWindow
{
    Q_OBJECT
public:
//    explicit PlayScene(QWidget *parent = nullptr);
    PlayScene(int levelNum);
    int levelIndex;//内部成员,记录所选的关卡

    //重写绘图事件
    void paintEvent(QPaintEvent *ev);

signals:
//    void playscene();
    //自定义信号,告诉选择关卡场景点击了返回
    void ChooseSceneBack();

};

#endif // PLAYSCENE_H

在这里插入图片描述
(2)在翻金币场景中,通过点击返回按钮释放信号

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    //点击退出,退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });
}


(3)选择关卡场景中,监听发送的信号

ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
    //1.配置选择关卡场景
    //(1)设置场景界面大小
    this->setFixedSize(320,588);
    //(2)设置图标
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    //(3)设置标题
    this->setWindowTitle("选择关卡场景");
    //(4)创建菜单栏   #include <QMenuBar>
    QMenuBar *bar=menuBar();
    setMenuBar(bar);
    //(5)创建开始菜单 #include <QMenu>
    QMenu *startMenu=bar->addMenu("开始");
    //(6)创建菜单项
    QAction *quitAction=startMenu->addAction("退出");
    //(7)点击退出,实现退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });


    //2.返回按钮
    //#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    //(2)点击返回,切换至主场景
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });

    //3.创建选择关卡的按钮
    for (int i=0;i<20;i++)
    {
        //自定义按钮:构造函数包含两个参数
        MyPushButton *menuBtn=new MyPushButton(":/res/LevelIcon.png");
        menuBtn->setParent(this);
        menuBtn->move(i%4*70+25,i/4*70+100);

        //设置文字标签
        QLabel *label=new QLabel;
        label->setParent(this);
        label->setFixedSize(menuBtn->width(),menuBtn->height());
        label->setText(QString::number(i+1));//标签上的文字
        label->move(i%4*70+25,i/4*70+100);
        label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//文字水平和垂直居中
        //设置让鼠标进行穿透,否者label覆盖按钮,不能执行操作
        label->setAttribute(Qt::WA_TransparentForMouseEvents);

        //监听每个按钮的点击事件
        connect(menuBtn,&QPushButton::clicked,[=]()
        {
           //#include "playscene.h"
           this->hide();//隐藏选择关卡场景
           this->play=new PlayScene(i+1);//创建翻金币场景
           play->show();//显示翻金币场景

           //监听翻金币场景的返回按钮信号
           connect(play,&PlayScene::ChooseSceneBack,[=]()
           {
               play->hide();
               delete play;
               play=NULL;
               this->show();
           });
        });
    }
}

在这里插入图片描述

4.4 显示选择的关卡号

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    //点击退出,退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);
}

在这里插入图片描述

4.5 创建金币背景图片

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    //点击退出,退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);
        }
    }
}

在这里插入图片描述

4.6 创建金币类

4.6.1 创建金币类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
修改基类
在这里插入图片描述
在这里插入图片描述

4.6.2 金币类构造函数

(1)构造函数声明

#ifndef MYCOIN_H
#define MYCOIN_H

//#include <QWidget>
#include <QPushButton>

class MyCoin : public QPushButton
{
    Q_OBJECT
public:
//    explicit MyCoin(QWidget *parent = nullptr);
    //构造函数:传入的金币路径,是金币还是银币
    MyCoin (QString btnImg);
    
signals:

};
#endif // MYCOIN_H

在这里插入图片描述
(2)构造函数实现

#include "mycoin.h"

//MyCoin::MyCoin(QWidget *parent) : QPushButton(parent)
//{

//}

#include <QPixmap>
#include <QDebug>
MyCoin::MyCoin(QString btnImg)
{
    //加载图片
    QPixmap pix;
    bool ret=pix.load(btnImg);
    if(!ret)
    {
        QString str =QString("图片加载失败");
        qDebug()<<str;
        return ;
    }
    this->setFixedSize(pix.width(),pix.height());
    this->setStyleSheet("QPushButoon{border:0px}");
    this->setIcon(pix);
    this->setIconSize(QSize(pix.width(),pix.height()));
}

在这里插入图片描述
(3)测试:包含金币类头文件playscene.cpp中

#include "mycoin.h"
PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });//点击退出,退出游戏


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);

            //创建金币
            MyCoin *coin =new MyCoin(":/res/Coin0001.png");
            coin->setParent(this);
            coin->move(59+i*50,204+j*50);
        }
    }
}

在这里插入图片描述

4.7 引入关卡数据

(1)添加配置文件(cpp/h)到翻金币项目中
在这里插入图片描述
在这里插入图片描述
(2)将配置文件设置为资源文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.8 初始化各个关卡

(1)在playscene.h中声明二维数组,维护每个关卡的具体数据。

#ifndef PLAYSCENE_H
#define PLAYSCENE_H

#include <QMainWindow>

class PlayScene : public QMainWindow
{
    Q_OBJECT
public:
//    explicit PlayScene(QWidget *parent = nullptr);
    PlayScene(int levelNum);
    int levelIndex;//内部成员,记录所选的关卡

    //重写绘图事件
    void paintEvent(QPaintEvent *ev);
    
    int gameArray[4][4];//二维数组,维护每个关卡的具体数据

signals:
//    void playscene();
    //自定义信号,告诉选择关卡场景点击了返回
    void ChooseSceneBack();

};

#endif // PLAYSCENE_H

在这里插入图片描述

(2)在palyscene.cpp中初始化每个关卡的二维数组。

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });//点击退出,退出游戏


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //初始化关卡的二维数组
    dataConfig config;
    for(int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            //#include "dataconfig.h"
            this->gameArray[i][j]=config.mData[this->levelIndex][i][j];
        }
    }
    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);
            //创建金币(根据关卡的二维数组创建)
            QString str;
            if(this->gameArray[i][j]==1)
            {
                str=":/res/Coin0001.png";
            }
            else
            {
                str=":/res/Coin0008.png";
            }
            MyCoin *coin =new MyCoin(str);
            coin->setParent(this);
            coin->move(59+i*50,204+j*50);
        }
    }
}

在这里插入图片描述

(3)金币类增加位置及标志属性:mycoin.h

#ifndef MYCOIN_H
#define MYCOIN_H

//#include <QWidget>
#include <QPushButton>

class MyCoin : public QPushButton
{
    Q_OBJECT
public:
//    explicit MyCoin(QWidget *parent = nullptr);
    //构造函数:传入的金币路径,是金币还是银币
    MyCoin (QString btnImg);
    
    //金币属性
    int posX;//x坐标位置
    int posY;//y坐标位置
    bool flag;//代表正反面

signals:

};

#endif // MYCOIN_H

在这里插入图片描述
(4)在创建关卡的场景中,对金币类的各个属性同时赋值:palyscene.cpp

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });//点击退出,退出游戏


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //初始化关卡的二维数组
    dataConfig config;
    for(int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            //#include "dataconfig.h"
            this->gameArray[i][j]=config.mData[this->levelIndex][i][j];
        }
    }
    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);
            //创建金币(根据关卡的二维数组创建)
            QString str;
            if(this->gameArray[i][j]==1)
            {
                str=":/res/Coin0001.png";
            }
            else
            {
                str=":/res/Coin0008.png";
            }
            MyCoin *coin =new MyCoin(str);
            coin->setParent(this);
            coin->move(59+i*50,204+j*50);
            //给金币属性赋值
            coin->posX=i;
            coin->posY=j;
            coin->flag=this->gameArray[i][j];
        }
    }
}

在这里插入图片描述

4.9 金币翻转特效实现

4.9.1 MyCoin类拓展属性和行为

(1)在mycoin.h头文件中声明属性和行为

#ifndef MYCOIN_H
#define MYCOIN_H

//#include <QWidget>
#include <QPushButton>
#include <QTimer>

class MyCoin : public QPushButton
{
    Q_OBJECT
public:
//    explicit MyCoin(QWidget *parent = nullptr);
    //构造函数:传入的金币路径,是金币还是银币
    MyCoin (QString btnImg);
    
    //金币属性
    int posX;//x坐标位置
    int posY;//y坐标位置
    bool flag;//代表正反面
    
    //改变标志的方法
    void changeFlag();
    QTimer * timer1;//正面翻反面的计时器
    QTimer * timer2;//反面翻正面的定时器
    int min=1;
    int max=8;
    
 //执行动画标志
    bool isAnimation=false;
    
signals:

};

#endif // MYCOIN_H


在这里插入图片描述

(2)在mycoin.cpp中实现方法

#include "mycoin.h"

//MyCoin::MyCoin(QWidget *parent) : QPushButton(parent)
//{

//}

#include <QPixmap>
#include <QDebug>

MyCoin::MyCoin(QString btnImg)
{
    //加载图片
    QPixmap pix;
    bool ret=pix.load(btnImg);
    if(!ret)
    {
        QString str =QString("图片加载失败");
        qDebug()<<str;
        return ;
    }
    this->setFixedSize(pix.width(),pix.height());
    this->setStyleSheet("QPushButton{border:0px}");
    this->setIcon(pix);
    this->setIconSize(QSize(pix.width(),pix.height()));

    //初始化定时器对象
    timer1=new QTimer(this);
    timer2=new QTimer(this);

    //监听正反面翻转的信号,并且翻转金币
    connect(timer1,&QTimer::timeout,[=]()
    {
       QPixmap pix;
       QString str=QString(":/res/Coin000%1.png").arg(this->min++);
       pix.load(str);

       this->setFixedSize(pix.width(),pix.height());
       this->setStyleSheet("QPushButton{border:0px}");
       this->setIcon(pix);
       this->setIconSize(QSize(pix.width(),pix.height()));

       //判断如果翻转玩了,将min重置为1
       if (this->min >this->max)
       {
           this->min=1;
           isAnimation=false;
           timer1->stop();
       }
    });
    //监听正反面翻转的信号,并且翻转金币
    connect(timer2,&QTimer::timeout,[=]()
    {
       QPixmap pix;
       QString str=QString(":/res/Coin000%1.png").arg(this->max--);
       pix.load(str);

       this->setFixedSize(pix.width(),pix.height());
       this->setStyleSheet("QPushButton{border:0px}");
       this->setIcon(pix);
       this->setIconSize(QSize(pix.width(),pix.height()));

       //判断如果翻转玩了,将min重置为1
       if (this->max <this->min)
       {
           this->max=8;
           isAnimation=false;
           timer2->stop();
       }
    });
}
//改变标志的方法
void MyCoin::changeFlag()
{
    //如果是正面
    if(this->flag)
    {
        //开启正面翻反面的定时器
        timer1->start(30);
        isAnimation=true;//开始执行动画
        this->flag=false;
    }
    else
    {
        //开启反面翻反面的定时器
        timer2->start(30);
        isAnimation=true;//开始执行动画
        this->flag=true;
    }
}

在这里插入图片描述

(3)在翻金币场景中,使用翻转特效:playscene.cpp

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });//点击退出,退出游戏


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //初始化关卡的二维数组
    dataConfig config;
    for(int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            //#include "dataconfig.h"
            this->gameArray[i][j]=config.mData[this->levelIndex][i][j];
        }
    }
    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);
            //创建金币(根据关卡的二维数组创建)
            QString str;
            if(this->gameArray[i][j]==1)
            {
                str=":/res/Coin0001.png";
            }
            else
            {
                str=":/res/Coin0008.png";
            }
            MyCoin *coin =new MyCoin(str);
            coin->setParent(this);
            coin->move(59+i*50,204+j*50);
            //给金币属性赋值
            coin->posX=i;
            coin->posY=j;
            coin->flag=this->gameArray[i][j];

           //点击金币进行翻转
            connect(coin,&MyCoin::clicked,[=]()
            {
                coin->changeFlag();
            });
        }
    }
}

在这里插入图片描述

4.9.2 重写按下事件

(1)鼠标按下事件操作声明

#ifndef MYCOIN_H
#define MYCOIN_H

//#include <QWidget>
#include <QPushButton>
#include <QTimer>

class MyCoin : public QPushButton
{
    Q_OBJECT
public:
//    explicit MyCoin(QWidget *parent = nullptr);
    //构造函数:传入的金币路径,是金币还是银币
    MyCoin (QString btnImg);

    //金币属性
    int posX;//x坐标位置
    int posY;//y坐标位置
    bool flag;//代表正反面

    //改变标志的方法
    void changeFlag();
    QTimer * timer1;//正面翻反面的计时器
    QTimer * timer2;//反面翻正面的定时器
    int min=1;
    int max=8;
    
    //执行动画标志
    bool isAnimation=false;
    
    //重写按下和释放事件
    void mousePressEvent(QMouseEvent *ev);
//    void mouseReleaseEvent(QMouseEvent *ev);

signals:

};

#endif // MYCOIN_H

在这里插入图片描述
(2)鼠标按下事件实现

//重写按下和释放事件
void MyCoin::mousePressEvent(QMouseEvent *ev)
{
    if (this->isAnimation)
    {
        return;
    }
    else
    {
       QPushButton::mousePressEvent(ev);//交给父类处理
    }
    
}

在这里插入图片描述

4.10 周围金币翻转

(1)创建金币(硬币)二维数组,维护金币(硬币)

#ifndef PLAYSCENE_H
#define PLAYSCENE_H

#include <QMainWindow>
#include <mycoin.h>

class PlayScene : public QMainWindow
{
    Q_OBJECT
public:
//    explicit PlayScene(QWidget *parent = nullptr);
    PlayScene(int levelNum);
    int levelIndex;//内部成员,记录所选的关卡

    //重写绘图事件
    void paintEvent(QPaintEvent *ev);

    int gameArray[4][4];//二维数组,维护每个关卡的具体数据
   
    MyCoin *coinBtn[4][4];//金币二维数组,方便后期维护
    

signals:
//    void playscene();
    //自定义信号,告诉选择关卡场景点击了返回
    void ChooseSceneBack();
 
};

#endif // PLAYSCENE_H

在这里插入图片描述
(2)将金币放入金币二维数组,以便后期维护,并进行金币翻转的关联:palyscene.cpp

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });//点击退出,退出游戏


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //初始化关卡的二维数组
    dataConfig config;
    for(int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            //#include "dataconfig.h"
            this->gameArray[i][j]=config.mData[this->levelIndex][i][j];
        }
    }
    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);
            //创建金币(根据关卡的二维数组创建)
            QString str;
            if(this->gameArray[i][j]==1)
            {
                str=":/res/Coin0001.png";
            }
            else
            {
                str=":/res/Coin0008.png";
            }
            MyCoin *coin =new MyCoin(str);
            coin->setParent(this);
            coin->move(59+i*50,204+j*50);
            //给金币属性赋值
            coin->posX=i;
            coin->posY=j;
            coin->flag=this->gameArray[i][j];

            //将金币放入金币二维数组,方便后期维护
            coinBtn[i][j]=coin;

           //点击金币进行翻转
            connect(coin,&MyCoin::clicked,[=]()
            {
                coin->changeFlag();
                this->gameArray[i][j]=this->gameArray[i][j]==0?1:0;
                //翻转周围的硬币
                if(coin->posX+1<=3)//右侧金币翻转
                {
                    coinBtn[coin->posX+1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX+1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posX-1>=0)//左侧金币翻转
                {
                    coinBtn[coin->posX-1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX-1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY+1<=3)//下侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY+1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY+1]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY-1>=0)//上侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY-1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY-1]=
                            this->gameArray[i][j]==0?1:0;
                }

            });
        }
    }
}

在这里插入图片描述

4.11 判断游戏胜利并且禁用按钮

4.11.1 判断游戏是否胜利

(1)添加是否胜利的标志:playscene.h

#ifndef PLAYSCENE_H
#define PLAYSCENE_H

#include <QMainWindow>
#include <mycoin.h>

class PlayScene : public QMainWindow
{
    Q_OBJECT
public:
//    explicit PlayScene(QWidget *parent = nullptr);
    PlayScene(int levelNum);
    int levelIndex;//内部成员,记录所选的关卡

    //重写绘图事件
    void paintEvent(QPaintEvent *ev);

    int gameArray[4][4];//二维数组,维护每个关卡的具体数据

    MyCoin *coinBtn[4][4];//金币二维数组,方便后期维护
    
    //是否胜利的标志
       bool isWin;


signals:
//    void playscene();
    //自定义信号,告诉选择关卡场景点击了返回
    void ChooseSceneBack();

};

#endif // PLAYSCENE_H

在这里插入图片描述
(2)判断游戏是否胜利:playscene.cpp

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });//点击退出,退出游戏


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //初始化关卡的二维数组
    dataConfig config;
    for(int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            //#include "dataconfig.h"
            this->gameArray[i][j]=config.mData[this->levelIndex][i][j];
        }
    }
    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);
            //创建金币(根据关卡的二维数组创建)
            QString str;
            if(this->gameArray[i][j]==1)
            {
                str=":/res/Coin0001.png";
            }
            else
            {
                str=":/res/Coin0008.png";
            }
            MyCoin *coin =new MyCoin(str);
            coin->setParent(this);
            coin->move(59+i*50,204+j*50);
            //给金币属性赋值
            coin->posX=i;
            coin->posY=j;
            coin->flag=this->gameArray[i][j];

            //将金币放入金币二维数组,方便后期维护
            coinBtn[i][j]=coin;

           //点击金币进行翻转
            connect(coin,&MyCoin::clicked,[=]()
            {
                coin->changeFlag();
                this->gameArray[i][j]=this->gameArray[i][j]==0?1:0;
                //翻转周围的硬币
                if(coin->posX+1<=3)//右侧金币翻转
                {
                    coinBtn[coin->posX+1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX+1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posX-1>=0)//左侧金币翻转
                {
                    coinBtn[coin->posX-1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX-1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY+1<=3)//下侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY+1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY+1]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY-1>=0)//上侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY-1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY-1]=
                            this->gameArray[i][j]==0?1:0;
                }
                
                //判断是否胜利
                this->isWin=true;
                for(int i=0;i<4;i++)
                {
                    for (int j=0;j<4;j++)
                    {
                        if(coinBtn[i][j]->flag==false)
                        {
                            this->isWin=false;
                            break;
                        }
                    }
                }
                if (this->isWin)
                {
                    //胜利
                    qDebug()<<"游戏胜利";
                }
            });
        }
    }
}

在这里插入图片描述

4.11.2 游戏胜利禁用按钮

(1)按钮类增加是否胜利的标志:mycoin.h

#ifndef MYCOIN_H
#define MYCOIN_H

//#include <QWidget>
#include <QPushButton>
#include <QTimer>

class MyCoin : public QPushButton
{
    Q_OBJECT
public:
//    explicit MyCoin(QWidget *parent = nullptr);
    //构造函数:传入的金币路径,是金币还是银币
    MyCoin (QString btnImg);

    //金币属性
    int posX;//x坐标位置
    int posY;//y坐标位置
    bool flag;//代表正反面

    //改变标志的方法
    void changeFlag();
    QTimer * timer1;//正面翻反面的计时器
    QTimer * timer2;//反面翻正面的定时器
    int min=1;
    int max=8;

    //执行动画标志
    bool isAnimation=false;

    //重写按下和释放事件
    void mousePressEvent(QMouseEvent *ev);
//    void mouseReleaseEvent(QMouseEvent *ev);
    
    //是否胜利的标志
    bool isWin=false;
signals:
};
#endif // MYCOIN_H

在这里插入图片描述

(2)游戏胜利后,将所有按钮的胜利标志改为true:palyscene.cpp

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });//点击退出,退出游戏


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //初始化关卡的二维数组
    dataConfig config;
    for(int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            //#include "dataconfig.h"
            this->gameArray[i][j]=config.mData[this->levelIndex][i][j];
        }
    }
    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);
            //创建金币(根据关卡的二维数组创建)
            QString str;
            if(this->gameArray[i][j]==1)
            {
                str=":/res/Coin0001.png";
            }
            else
            {
                str=":/res/Coin0008.png";
            }
            MyCoin *coin =new MyCoin(str);
            coin->setParent(this);
            coin->move(59+i*50,204+j*50);
            //给金币属性赋值
            coin->posX=i;
            coin->posY=j;
            coin->flag=this->gameArray[i][j];

            //将金币放入金币二维数组,方便后期维护
            coinBtn[i][j]=coin;

           //点击金币进行翻转
            connect(coin,&MyCoin::clicked,[=]()
            {
                coin->changeFlag();
                this->gameArray[i][j]=this->gameArray[i][j]==0?1:0;
                //翻转周围的硬币
                if(coin->posX+1<=3)//右侧金币翻转
                {
                    coinBtn[coin->posX+1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX+1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posX-1>=0)//左侧金币翻转
                {
                    coinBtn[coin->posX-1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX-1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY+1<=3)//下侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY+1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY+1]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY-1>=0)//上侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY-1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY-1]=
                            this->gameArray[i][j]==0?1:0;
                }
                
                //判断是否胜利
                this->isWin=true;
                for(int i=0;i<4;i++)
                {
                    for (int j=0;j<4;j++)
                    {
                        if(coinBtn[i][j]->flag==false)
                        {
                            this->isWin=false;
                            break;
                        }
                    }
                }
                if (this->isWin)
                {
                    //胜利
                    qDebug()<<"游戏胜利";
                    //将所有按钮的胜利标志改为true
                    for(int i=0;i<4;i++)
                    {
                        for (int j=0;j<4;j++)
                        {
                            coinBtn[i][j]->isWin=true;
                        }
                    }
                }
            });
        }
    }
}

在这里插入图片描述
(3)修改按钮类的按下事件,通过判断按钮是否胜利,来禁止或允许按钮可以按下:mycoin.cpp

//重写按下和释放事件
void MyCoin::mousePressEvent(QMouseEvent *ev)
{
    if (this->isAnimation || this->isWin)
    {
        return;
    }
    else
    {
       QPushButton::mousePressEvent(ev);//交给父类处理
    }

}

在这里插入图片描述

4.12 胜利图片显示

(1)胜利图片创建——》利用Qlabel,但是隐藏显示

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });//点击退出,退出游戏


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //初始化关卡的二维数组
    dataConfig config;
    for(int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            //#include "dataconfig.h"
            this->gameArray[i][j]=config.mData[this->levelIndex][i][j];
        }
    }


    //胜利图片显示
    QLabel *winLabel=new QLabel;
    QPixmap tmpPix;
    tmpPix.load(":/res/LevelCompleteDialogBg.png");
    winLabel->setGeometry(0,0,tmpPix.width(),tmpPix.height());
    winLabel->setPixmap(tmpPix);
    winLabel->setParent(this);
    winLabel->move((this->width()-tmpPix.width())*0.5,-tmpPix.height());


    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);
            //创建金币(根据关卡的二维数组创建)
            QString str;
            if(this->gameArray[i][j]==1)
            {
                str=":/res/Coin0001.png";
            }
            else
            {
                str=":/res/Coin0008.png";
            }
            MyCoin *coin =new MyCoin(str);
            coin->setParent(this);
            coin->move(59+i*50,204+j*50);
            //给金币属性赋值
            coin->posX=i;
            coin->posY=j;
            coin->flag=this->gameArray[i][j];

            //将金币放入金币二维数组,方便后期维护
            coinBtn[i][j]=coin;

           //点击金币进行翻转
            connect(coin,&MyCoin::clicked,[=]()
            {
                coin->changeFlag();
                this->gameArray[i][j]=this->gameArray[i][j]==0?1:0;
                //翻转周围的硬币
                if(coin->posX+1<=3)//右侧金币翻转
                {
                    coinBtn[coin->posX+1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX+1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posX-1>=0)//左侧金币翻转
                {
                    coinBtn[coin->posX-1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX-1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY+1<=3)//下侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY+1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY+1]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY-1>=0)//上侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY-1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY-1]=
                            this->gameArray[i][j]==0?1:0;
                }

                //判断是否胜利
                this->isWin=true;
                for(int i=0;i<4;i++)
                {
                    for (int j=0;j<4;j++)
                    {
                        if(coinBtn[i][j]->flag==false)
                        {
                            this->isWin=false;
                            break;
                        }
                    }
                }
                if (this->isWin==true)
                {
                    //胜利
                    qDebug()<<"游戏胜利";
                    //将所有按钮的胜利标志改为true
                    for(int i=0;i<4;i++)
                    {
                        for (int j=0;j<4;j++)
                        {
                            coinBtn[i][j]->isWin=true;
                        }
                    }
                    //显示胜利图片
                    
                }
            });
        }
    }
}

在这里插入图片描述
(2)当胜利的时候,显现胜利图片

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });//点击退出,退出游戏


    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //初始化关卡的二维数组
    dataConfig config;
    for(int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            //#include "dataconfig.h"
            this->gameArray[i][j]=config.mData[this->levelIndex][i][j];
        }
    }


    //胜利图片显示
    QLabel *winLabel=new QLabel;
    QPixmap tmpPix;
    tmpPix.load(":/res/LevelCompleteDialogBg.png");
    winLabel->setGeometry(0,0,tmpPix.width(),tmpPix.height());
    winLabel->setParent(this);
    winLabel->move((this->width()-tmpPix.width())*0.5,-tmpPix.height());


    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);
            //创建金币(根据关卡的二维数组创建)
            QString str;
            if(this->gameArray[i][j]==1)
            {
                str=":/res/Coin0001.png";
            }
            else
            {
                str=":/res/Coin0008.png";
            }
            MyCoin *coin =new MyCoin(str);
            coin->setParent(this);
            coin->move(59+i*50,204+j*50);
            //给金币属性赋值
            coin->posX=i;
            coin->posY=j;
            coin->flag=this->gameArray[i][j];

            //将金币放入金币二维数组,方便后期维护
            coinBtn[i][j]=coin;

           //点击金币进行翻转
            connect(coin,&MyCoin::clicked,[=]()
            {
                coin->changeFlag();
                this->gameArray[i][j]=this->gameArray[i][j]==0?1:0;
                //翻转周围的硬币
                if(coin->posX+1<=3)//右侧金币翻转
                {
                    coinBtn[coin->posX+1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX+1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posX-1>=0)//左侧金币翻转
                {
                    coinBtn[coin->posX-1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX-1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY+1<=3)//下侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY+1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY+1]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY-1>=0)//上侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY-1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY-1]=
                            this->gameArray[i][j]==0?1:0;
                }

                //判断是否胜利
                this->isWin=true;
                for(int i=0;i<4;i++)
                {
                    for (int j=0;j<4;j++)
                    {
                        if(coinBtn[i][j]->flag==false)
                        {
                            this->isWin=false;
                            break;
                        }
                    }
                }
                if (this->isWin==true)
                {
                    //胜利
                    qDebug()<<"游戏胜利";
                    //将所有按钮的胜利标志改为true
                    for(int i=0;i<4;i++)
                    {
                        for (int j=0;j<4;j++)
                        {
                            coinBtn[i][j]->isWin=true;
                        }
                    }
                    //显示胜利图片,将图片移动下来显现
                    //#include <QPropertyAnimation>
                    //#include <QRect>

                    QPropertyAnimation *annimation=new QPropertyAnimation
                            (winLabel,"geometry");
                    annimation->setDuration(1000);//时间间隔
                    annimation->setStartValue(QRect(winLabel->x(),
                                                    winLabel->y(),
                                                 winLabel->width(),
                                                    winLabel->height()));
                    annimation->setEndValue(QRect(winLabel->x(),
                                                  winLabel->y()+114,
                                               winLabel->width(),
                                                  winLabel->height()));
                    annimation->setEasingCurve(QEasingCurve::OutBounce);
                    annimation->start();
                    
                }
            });
        }
    }
}

在这里插入图片描述

5 音效添加

5.1 开始游戏音效

主场景中,点击开始按钮,播放音效:mainscene.cpp
(1)在项目配置文件(.pro)中包含音效的库(媒体)
在这里插入图片描述
(2)开始按钮的特效:mainscene.cpp

MainScene::MainScene(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainScene)
{
    ui->setupUi(this);
    //(1)配置主场景
    //设置固定大小
    setFixedSize(320,588);
    //设置窗口图标
    setWindowIcon(QIcon(":/res/Coin0001.png"));
    //设置标题
    setWindowTitle(" 翻金币主场景");
    //退出菜单项实现
    connect(ui->actionquit,&QAction::triggered,[=]()
    {
       this->close();
    });


    //准备开始按钮的音效
    QSound *startSound=new QSound(":/res/TapButtonSound.wav",this);
    
    
    //(2)开始按钮,跳转到选择关卡场景
    //#include "mypushbutton.h"
    MyPushButton *startBtn=new MyPushButton(":/res/MenuSceneStartButton.png");
    startBtn->setParent(this);
    startBtn->move(this->width()*0.5-startBtn->width()*0.5,
                   this->height()*0.7);

    chooseScene =new ChooseLevelScene;//实例化选择关卡场景
    connect(startBtn,&MyPushButton::clicked,[=]()
    {
        //播放音效
        startSound->play();
        
        //弹跳特效
        startBtn->zoom1();
        startBtn->zoom2();
        //进入选择关卡场景
        QTimer::singleShot(500,this,[=]()
        {
            this->hide();//当前窗口隐藏
            chooseScene->show();//显示选择关卡场景
        });//延时进入
    });

    //(3)监听选择关卡场景的信号#include <chooselevelscene.h>
    connect(chooseScene,&ChooseLevelScene::ChooseSceneBack,[=]()
    {
        chooseScene->hide();
        this->show();
    });
}

在这里插入图片描述

5.2 选择关卡音效

选择关卡场景中,点击关卡按钮,播放音效:chooselevelscene.cpp

ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
    //1.配置选择关卡场景
    //(1)设置场景界面大小
    this->setFixedSize(320,588);
    //(2)设置图标
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    //(3)设置标题
    this->setWindowTitle("选择关卡场景");
    //(4)创建菜单栏   #include <QMenuBar>
    QMenuBar *bar=menuBar();
    setMenuBar(bar);
    //(5)创建开始菜单 #include <QMenu>
    QMenu *startMenu=bar->addMenu("开始");
    //(6)创建菜单项
    QAction *quitAction=startMenu->addAction("退出");
    //(7)点击退出,实现退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });


    //2.返回按钮
    //#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    
    //选择关卡按钮音效
    QSound *chooseSound=new QSound(":/res/TapButtonSound.wav",this);
    
    
    //(2)点击返回,切换至主场景
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });
    //3.创建选择关卡的按钮
    for (int i=0;i<20;i++)
    {
        //自定义按钮:构造函数包含两个参数
        MyPushButton *menuBtn=new MyPushButton(":/res/LevelIcon.png");
        menuBtn->setParent(this);
        menuBtn->move(i%4*70+25,i/4*70+100);

        //设置文字标签
        QLabel *label=new QLabel;
        label->setParent(this);
        label->setFixedSize(menuBtn->width(),menuBtn->height());
        label->setText(QString::number(i+1));//标签上的文字
        label->move(i%4*70+25,i/4*70+100);
        label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//文字水平和垂直居中
        //设置让鼠标进行穿透,否者label覆盖按钮,不能执行操作
        label->setAttribute(Qt::WA_TransparentForMouseEvents);

        //监听每个按钮的点击事件
        connect(menuBtn,&QPushButton::clicked,[=]()
        {
            //播放选择关卡按钮的音效
            chooseSound->play();
            
           //#include "playscene.h"
           this->hide();//隐藏选择关卡场景
           this->play=new PlayScene(i+1);//创建翻金币场景
           play->show();//显示翻金币场景

           //监听翻金币场景的返回按钮信号
           connect(play,&PlayScene::ChooseSceneBack,[=]()
           {
               play->hide();
               delete play;
               play=NULL;
               this->show();
           });
        });

    }

}

在这里插入图片描述

5.3 返回按钮音效

选择关卡场景中,点击返回按钮,播放音效:chooselevelscene.cpp

ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
    //1.配置选择关卡场景
    //(1)设置场景界面大小
    this->setFixedSize(320,588);
    //(2)设置图标
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    //(3)设置标题
    this->setWindowTitle("选择关卡场景");
    //(4)创建菜单栏   #include <QMenuBar>
    QMenuBar *bar=menuBar();
    setMenuBar(bar);
    //(5)创建开始菜单 #include <QMenu>
    QMenu *startMenu=bar->addMenu("开始");
    //(6)创建菜单项
    QAction *quitAction=startMenu->addAction("退出");
    //(7)点击退出,实现退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });


    //2.返回按钮
    //#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    
    //选择关卡按钮音效
    QSound *chooseSound=new QSound(":/res/TapButtonSound.wav",this);
    //返回按钮音效
    QSound *backSound=new QSound(":/res/BackButtonSound.wav",this);
    
    //(2)点击返回,切换至主场景
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        //播放返回按钮的音效
        backSound->play();
        
        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
        
    });
    //3.创建选择关卡的按钮
    for (int i=0;i<20;i++)
    {
        //自定义按钮:构造函数包含两个参数
        MyPushButton *menuBtn=new MyPushButton(":/res/LevelIcon.png");
        menuBtn->setParent(this);
        menuBtn->move(i%4*70+25,i/4*70+100);

        //设置文字标签
        QLabel *label=new QLabel;
        label->setParent(this);
        label->setFixedSize(menuBtn->width(),menuBtn->height());
        label->setText(QString::number(i+1));//标签上的文字
        label->move(i%4*70+25,i/4*70+100);
        label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//文字水平和垂直居中
        //设置让鼠标进行穿透,否者label覆盖按钮,不能执行操作
        label->setAttribute(Qt::WA_TransparentForMouseEvents);

        //监听每个按钮的点击事件
        connect(menuBtn,&QPushButton::clicked,[=]()
        {
            //播放选择关卡按钮的音效
            chooseSound->play();
            
           //#include "playscene.h"
           this->hide();//隐藏选择关卡场景
           this->play=new PlayScene(i+1);//创建翻金币场景
           play->show();//显示翻金币场景

           //监听翻金币场景的返回按钮信号
           connect(play,&PlayScene::ChooseSceneBack,[=]()
           {
               play->hide();
               delete play;
               play=NULL;
               this->show();
           });
        });
    }
}

在这里插入图片描述

5.4 翻金币与胜利音效

翻金币场景中,点击金币按钮、以及胜利,播放音效:playscene.cpp
(1)返回按钮音效
在这里插入图片描述
(2) 翻金币与游戏胜利音效
在这里插入图片描述
在这里插入图片描述

PlayScene::PlayScene(int levelNum)
{
    qDebug()<<QString("进入第%1关").arg(levelNum);
    this->levelIndex=levelNum;

    //翻金币场景基本配置
    this->setFixedSize(320,588);//设置窗口大小
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//窗口图标
    this->setWindowTitle("翻金币场景");//窗口标题
    QMenuBar *bar=menuBar();//创建菜单栏
    setMenuBar(bar);
    QMenu *startMenu=bar->addMenu("开始");//创建菜单
    QAction *quitAction=startMenu->addAction("退出");//创建菜单项
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });//点击退出,退出游戏

    //添加返回按钮音效资源
    QSound *backSound=new QSound(":/res/BackButtonSound.wav",this);
    //返回按钮#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        //播放返回的音效
        backSound->play();
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();
    });


    //显示选择的关卡号#include "QLabel"
    QLabel *label=new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("华文新魏");//#include <QFont>
    font.setPointSize(20);
    label->setFont(font);
    QString str2 =QString("Level:%1").arg(this->levelIndex);
    label->setText(str2);
    label->setGeometry(30,this->height()-50,120,50);


    //初始化关卡的二维数组
    dataConfig config;
    for(int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            //#include "dataconfig.h"
            this->gameArray[i][j]=config.mData[this->levelIndex][i][j];
        }
    }


    //胜利图片显示
    QLabel *winLabel=new QLabel;
    QPixmap tmpPix;
    tmpPix.load(":/res/LevelCompletedDialogBg.png");
    winLabel->setGeometry(0,0,tmpPix.width(),tmpPix.height());
    winLabel->setPixmap(tmpPix);
    winLabel->setParent(this);
    winLabel->move((this->width()-tmpPix.width())*0.5,-tmpPix.height());

    //添加翻金币与胜利的音效资源
    QSound *flipSound=new QSound(":/res/ConFlipSound.wav",this);
    QSound *winSound=new QSound(":/res/LevelWinSound.wav",this);
    
    //创建金币背景图片
    for (int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            //绘制金币背景图片
            QLabel *label =new QLabel;
            label->setGeometry(0,0,50,50);
            label->setPixmap(QPixmap(":/res/BoardNode.png"));
            label->setParent(this);
            label->move(57+i*50,200+j*50);
            //创建金币(根据关卡的二维数组创建)
            QString str;
            if(this->gameArray[i][j]==1)
            {
                str=":/res/Coin0001.png";
            }
            else
            {
                str=":/res/Coin0008.png";
            }
            MyCoin *coin =new MyCoin(str);
            coin->setParent(this);
            coin->move(59+i*50,204+j*50);
            //给金币属性赋值
            coin->posX=i;
            coin->posY=j;
            coin->flag=this->gameArray[i][j];

            //将金币放入金币二维数组,方便后期维护
            coinBtn[i][j]=coin;

           //点击金币进行翻转
            connect(coin,&MyCoin::clicked,[=]()
            {
                //翻金币音效
                flipSound->play();
                
                coin->changeFlag();
                this->gameArray[i][j]=this->gameArray[i][j]==0?1:0;
                //翻转周围的硬币
                if(coin->posX+1<=3)//右侧金币翻转
                {
                    coinBtn[coin->posX+1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX+1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posX-1>=0)//左侧金币翻转
                {
                    coinBtn[coin->posX-1][coin->posY]->changeFlag();
                    this->gameArray[coin->posX-1][coin->posY]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY+1<=3)//下侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY+1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY+1]=
                            this->gameArray[i][j]==0?1:0;
                }
                if(coin->posY-1>=0)//上侧金币翻转
                {
                    coinBtn[coin->posX][coin->posY-1]->changeFlag();
                    this->gameArray[coin->posX][coin->posY-1]=
                            this->gameArray[i][j]==0?1:0;
                }

                //判断是否胜利
                this->isWin=true;
                for(int i=0;i<4;i++)
                {
                    for (int j=0;j<4;j++)
                    {
                        if(coinBtn[i][j]->flag==false)
                        {
                            this->isWin=false;
                            break;
                        }
                    }
                }
                if (this->isWin==true)
                {
                    //游戏胜利音效
                    winSound->play();
                    //胜利
                    qDebug()<<"游戏胜利";
                    //将所有按钮的胜利标志改为true
                    for(int i=0;i<4;i++)
                    {
                        for (int j=0;j<4;j++)
                        {
                            coinBtn[i][j]->isWin=true;
                        }
                    }
                    //显示胜利图片,将图片移动下来显现
                    //#include <QPropertyAnimation>
                    //#include <QRect>

                    QPropertyAnimation *annimation=new QPropertyAnimation
                            (winLabel,"geometry");
                    annimation->setDuration(1000);//时间间隔
                    annimation->setStartValue(QRect(winLabel->x(),
                                                    winLabel->y(),
                                                 winLabel->width(),
                                                    winLabel->height()));
                    annimation->setEndValue(QRect(winLabel->x(),
                                                  winLabel->y()+114,
                                               winLabel->width(),
                                                  winLabel->height()));
                    annimation->setEasingCurve(QEasingCurve::OutBounce);
                    annimation->start();

                }
            });
        }
    }
}

6 项目优化场景切换的位置保持一致

(1)主场景与选择关卡场景保持位置一致

MainScene::MainScene(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainScene)
{
    ui->setupUi(this);
    //(1)配置主场景
    //设置固定大小
    setFixedSize(320,588);
    //设置窗口图标
    setWindowIcon(QIcon(":/res/Coin0001.png"));
    //设置标题
    setWindowTitle(" 翻金币主场景");
    //退出菜单项实现
    connect(ui->actionquit,&QAction::triggered,[=]()
    {
       this->close();
    });


    //准备开始按钮的音效
    QSound *startSound=new QSound(":/res/TapButtonSound.wav",this);


    //(2)开始按钮,跳转到选择关卡场景
    //#include "mypushbutton.h"
    MyPushButton *startBtn=new MyPushButton(":/res/MenuSceneStartButton.png");
    startBtn->setParent(this);
    startBtn->move(this->width()*0.5-startBtn->width()*0.5,
                   this->height()*0.7);

    chooseScene =new ChooseLevelScene;//实例化选择关卡场景
    connect(startBtn,&MyPushButton::clicked,[=]()
    {
        //播放音效
//        startSound->loops(-1);//无限循环音效
        startSound->play();

        //弹跳特效
        startBtn->zoom1();
        startBtn->zoom2();
        //进入选择关卡场景
        QTimer::singleShot(500,this,[=]()
        {
            //设置choosescene场景的位置
            chooseScene->setGeometry(this->geometry());
            
            this->hide();//当前窗口隐藏
            chooseScene->show();//显示选择关卡场景
        });//延时进入
    });

    //(3)监听选择关卡场景的信号#include <chooselevelscene.h>
    connect(chooseScene,&ChooseLevelScene::ChooseSceneBack,[=]()
    {
        this->setGeometry(chooseScene->geometry());
        chooseScene->hide();//将选择关卡场景的位置
        this->show();
    });
}

在这里插入图片描述
(2)选择关卡场景与关卡场景保持位置一致

ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
    //1.配置选择关卡场景
    //(1)设置场景界面大小
    this->setFixedSize(320,588);
    //(2)设置图标
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    //(3)设置标题
    this->setWindowTitle("选择关卡场景");
    //(4)创建菜单栏   #include <QMenuBar>
    QMenuBar *bar=menuBar();
    setMenuBar(bar);
    //(5)创建开始菜单 #include <QMenu>
    QMenu *startMenu=bar->addMenu("开始");
    //(6)创建菜单项
    QAction *quitAction=startMenu->addAction("退出");
    //(7)点击退出,实现退出游戏
    connect(quitAction,&QAction::triggered,[=]()
    {
       this->close();
    });


    //2.返回按钮
    //#include "mypushbutton.h"
    MyPushButton *backBtn=new MyPushButton(":/res/BackButton.png",
                                        ":/res/BackButtonSelected.png");
    backBtn->setParent(this);
    backBtn->move(this->width()-backBtn->width(),
                  this->height()-backBtn->height());

    //选择关卡按钮音效
    QSound *chooseSound=new QSound(":/res/TapButtonSound.wav",this);
    //返回按钮音效
    QSound *backSound=new QSound(":/res/BackButtonSound.wav",this);

    //(2)点击返回,切换至主场景
    connect (backBtn,&QPushButton::clicked,[=]()
    {
        //播放返回按钮的音效
        backSound->play();

//        qDebug()<<"点击返回按钮";
        //告诉主场景,按了返回按钮,主场景监听ChooseLevelScene的返回按钮
        emit this->ChooseSceneBack();

    });
    //3.创建选择关卡的按钮
    for (int i=0;i<20;i++)
    {
        //自定义按钮:构造函数包含两个参数
        MyPushButton *menuBtn=new MyPushButton(":/res/LevelIcon.png");
        menuBtn->setParent(this);
        menuBtn->move(i%4*70+25,i/4*70+100);

        //设置文字标签
        QLabel *label=new QLabel;
        label->setParent(this);
        label->setFixedSize(menuBtn->width(),menuBtn->height());
        label->setText(QString::number(i+1));//标签上的文字
        label->move(i%4*70+25,i/4*70+100);
        label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//文字水平和垂直居中
        //设置让鼠标进行穿透,否者label覆盖按钮,不能执行操作
        label->setAttribute(Qt::WA_TransparentForMouseEvents);

        //监听每个按钮的点击事件
        connect(menuBtn,&QPushButton::clicked,[=]()
        {
            //播放选择关卡按钮的音效
            chooseSound->play();
        
           //#include "playscene.h"
           this->hide();//隐藏选择关卡场景
           this->play=new PlayScene(i+1);//创建翻金币场景
            //设置游戏场景的初始位置
           play->setGeometry(this->geometry());
           play->show();//显示翻金币场景

           //监听翻金币场景的返回按钮信号
           connect(play,&PlayScene::ChooseSceneBack,[=]()
           {
               this->setGeometry(play->geometry());
               play->hide();
               delete play;
               play=NULL;
               this->show();
           });
        });

    }

}

在这里插入图片描述

7 项目打包及游戏扩展

7.1 项目打包

(1)设置程序发布状态:将Debug状态修改为程序发布状态
在这里插入图片描述
(2)重新编译项目
在这里插入图片描述
(3)打开项目所在文件,找到release版本的项目
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.2 游戏扩展

项目打包后生成的exe文件,要想使用,必须保持本机有qt的环境,因此为了扩展游戏,使得普通的电脑也可以运行程序,需要进行扩展。
(1)新建文件夹,并且将项目打包的exe文件复制到该文件夹内
在这里插入图片描述
(2)在文件夹内打开cmd命令窗口
在这里插入图片描述
(3)使用windeployqt 命令运行exe程序:生成打包项目
在这里插入图片描述
在这里插入图片描述

7.3 游戏打包nsis安装包(更深层拓展)

将游戏更深入打包,生成压缩包:参考:https://blog.csdn.net/signjing/article/details/7855855


版权声明:本文为qq_36926037原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。