QT学习日记22——翻金币游戏

学习视频链接

05 开始按钮创建_哔哩哔哩_bilibili05 开始按钮创建是最新QT从入门到实战完整版|传智教育的第46集视频,该合集共计63集,视频收藏或关注UP主,及时了解更多相关视频内容。https://www.bilibili.com/video/BV1g4411H78N?p=46&spm_id_from=333.1007.top_right_bar_window_history.content.click

项目资料,提取码 6666

百度网盘 请输入提取码

目录

一、主场景配置

1.1 设置窗口大小、图标、标题

1.2 开始菜单栏

1.3 槽函数

1.4 绘图事件

二、开始按钮的创建

2.1 新建类

2.2 构造函数

2.3 加入到主场景中

2.4 点击事件

2.5 平缓移动

三、新场景

3.1 创建新场景

3.2 进入新的场景

3.3 新场景设置

3.4 绘图事件 

3.5 返回按钮

3.6 选择关卡按钮

四、翻金币的场景 

4.1 创建类

4.2 选择关卡场景中添加关卡 

4.3 游戏场景中的配置

4.4 游戏场景返回到选择关卡

4.5 显示当前关卡数

4.6 显示金币背景图案

五、翻转金币

5.1 金币类

5.2 游戏场景中包含金币 

5.3 初始化金币银币数据

5.4 金币翻转特效实现

5.5 翻转周围的金币

5.7 周围延时翻转

六、胜利处理

6.1 胜利判断并禁用按钮

6.2 胜利图片实现

6.3 优化一些内容

6.5 设置音效

七、优化和发布

7.1 在每个场景中都保持在一个位置

7.2 打包发布


一、主场景配置

1.1 设置窗口大小、图标、标题

QT学习日记22——翻金币游戏_第1张图片

/* 配置主场景 */
// 设置固定大小
setFixedSize(320, 500);
// 设置图标
setWindowIcon(QIcon(":/res/Coin0001.png"));
// 设置标题
setWindowTitle("翻金币主场景");

1.2 开始菜单栏

QT学习日记22——翻金币游戏_第2张图片

1.3 槽函数

QT学习日记22——翻金币游戏_第3张图片

QT学习日记22——翻金币游戏_第4张图片

QT学习日记22——翻金币游戏_第5张图片

1.4 绘图事件

QT学习日记22——翻金币游戏_第6张图片

图片缩放

QT学习日记22——翻金币游戏_第7张图片

void MainScene::paintEvent(QPaintEvent *)
{
    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);  // 宽高变成原来的0.5
    painter.drawPixmap(10, 30, pix);
}

二、开始按钮的创建

2.1 新建类

QT学习日记22——翻金币游戏_第8张图片

 QT学习日记22——翻金币游戏_第9张图片

 QT学习日记22——翻金币游戏_第10张图片

2.2 构造函数

QT学习日记22——翻金币游戏_第11张图片

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

#include 
#include 

class MyPushButton : public QPushButton
{
    Q_OBJECT
public:
    // 构造函数 参数1:正常显示的图片路径 参数2:按下后显示的图片路径
    MyPushButton(QString normalImg, QString pressImg = "");

    // 成员属性 保存用户传入的默认显示路径以及按下后显示的图片路径
    QString normalImgPath;
    QString pressImgPath;

signals:

};

#endif // MYPUSHBUTTON_H

QT学习日记22——翻金币游戏_第12张图片

MyPushButton::MyPushButton(QString normalImg, QString pressImg)
{
    this->normalImgPath = normalImg;
    this->pressImgPath = pressImg;

    QPixmap pix;
    bool ret = pix.load(normalImg);
    if(!ret)
    {
        qDebug() << "图片加载失败";
        return;
    }

    // 设置图片固定大小
    this->setFixedSize(pix.width(), pix.height());

    // 设置不规则图片样式
    this->setStyleSheet("QPushButton{border:0px;}");

    // 设置图标
    this->setIcon(pix);

    // 设置图标大小
    this->setIconSize(QSize(pix.width(), pix.height()));
}

  

2.3 加入到主场景中

QT学习日记22——翻金币游戏_第13张图片

QT学习日记22——翻金币游戏_第14张图片

如果不设置不规则样式就会有这种情况

QT学习日记22——翻金币游戏_第15张图片

2.4 点击事件

QT学习日记22——翻金币游戏_第16张图片

2.5 平缓移动

QT学习日记22——翻金币游戏_第17张图片

QT学习日记22——翻金币游戏_第18张图片

void MyPushButton::zoom1()
{
    // 创建动态对象
    QPropertyAnimation *animation = new QPropertyAnimation(this, "geometry");
    // 设置动画时间间隔
    animation->setDuration(200);

    // 起始位置
    animation->setStartValue(QRect(this->x(), this->y(), this->width(), this->height()));
    // 结束位置
    animation->setEndValue(QRect(this->x(), this->y() + 10, this->width(), this->height()));

    // 设置弹跳曲线
    animation->setEasingCurve(QEasingCurve::OutBounce);
    // 执行动画
    animation->start();
}

QT学习日记22——翻金币游戏_第19张图片

QT学习日记22——翻金币游戏_第20张图片

右边就有了一个抖动的效果

三、新场景

3.1 创建新场景

添加新的场景类 ChooseLevelScene,把这个场景类放到主场景中

QT学习日记22——翻金币游戏_第21张图片

3.2 进入新的场景

构造函数中加入申请内存的代码,点击后隐藏自身并且显示选择关卡场景

QT学习日记22——翻金币游戏_第22张图片

直接跳转太僵硬了,所以加入延时和优化的效果

加入头文件 #include

QT学习日记22——翻金币游戏_第23张图片

3.3 新场景设置

添加头文件 #include

QT学习日记22——翻金币游戏_第24张图片

#include "chooselevelscene.h"

ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
    /* 选择关卡场景 */
    // 设置固定大小
    this->setFixedSize(320, 500);
    // 设置图标
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    // 设置标题
    this->setWindowTitle("选择关卡场景");

    // 创建菜单栏
    QMenuBar *menubar= menuBar();
    setMenuBar(menubar);
    // 创建开始菜单
    QMenu *menuStart = menubar->addMenu("开始");
    // 创建退出菜单项
    QAction *actionQuit = menuStart->addAction("退出");
    // 点击退出实现退出游戏
    connect(actionQuit, &QAction::triggered, [=](){
        this->close();
    });
}

3.4 绘图事件 

QT学习日记22——翻金币游戏_第25张图片

QT学习日记22——翻金币游戏_第26张图片

void ChooseLevelScene::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    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.5 返回按钮

使用我们封装好的按钮,我们包含一下按钮的头文件 #include "mypushbutton.h",

QT学习日记22——翻金币游戏_第27张图片

// 返回按钮
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, &MyPushButton::clicked, [=](){
    qDebug() << "点击了返回按钮";
});

重写按钮按下和释放事件

QT学习日记22——翻金币游戏_第28张图片

QT学习日记22——翻金币游戏_第29张图片

void MyPushButton::mousePressEvent(QMouseEvent *e)
{
    if(this->pressImgPath != "") // 传入的按下图片不为空 说明需要有按下状态,切换图片
    {
        QPixmap pix;
        bool ret = pix.load(this->pressImgPath);
        if(!ret)
        {
            qDebug() << "图片加载失败";
            return;
        }

        // 设置图片固定大小
        this->setFixedSize(pix.width(), pix.height());

        // 设置不规则图片样式
        this->setStyleSheet("QPushButton{border:0px;}");

        // 设置图标
        this->setIcon(pix);

        // 设置图标大小
        this->setIconSize(QSize(pix.width(), pix.height()));
    }

    // 让父类执行其他内容
    return QPushButton::mousePressEvent(e);
}

void MyPushButton::mouseReleaseEvent(QMouseEvent *e)
{
    if(this->pressImgPath != "") // 传入的按下图片不为空 说明需要有按下状态,切换图片
    {
        QPixmap pix;
        bool ret = pix.load(this->normalImgPath);
        if(!ret)
        {
            qDebug() << "图片加载失败";
            return;
        }

        // 设置图片固定大小
        this->setFixedSize(pix.width(), pix.height());

        // 设置不规则图片样式
        this->setStyleSheet("QPushButton{border:0px;}");

        // 设置图标
        this->setIcon(pix);

        // 设置图标大小
        this->setIconSize(QSize(pix.width(), pix.height()));
    }

    // 让父类执行其他内容
    return QPushButton::mouseReleaseEvent(e);
}

现在按钮点击和释放就有不同的样子了

写一个自定义信号,点击按钮后发出信号,主场景接受

QT学习日记22——翻金币游戏_第30张图片

QT学习日记22——翻金币游戏_第31张图片

// 点击返回
connect(backBtn, &MyPushButton::clicked, [=](){
    qDebug() << "点击了返回按钮";
    // 告诉主场景 我返回了,主场景监听chooseLevelScene的返回按钮
    emit this->chooseSceneBack();
});

QT学习日记22——翻金币游戏_第32张图片

// 监听选择关卡的返回按钮的信号
connect(chooseScene, &ChooseLevelScene::chooseSceneBack, this, [=]() {
    chooseScene->hide(); // 将选择关卡场景隐藏掉
    this->show();  // 重新显示主场景
});

3.6 选择关卡按钮

添加头文件 #include

QT学习日记22——翻金币游戏_第33张图片

在构造函数里面添加这些代码

// 创建选择关卡的按钮
for(int i = 0; i < 20; i++) {
    MyPushButton *menuBtn = new MyPushButton(":/res/LevelIcon.png");
    menuBtn->setParent(this);
    menuBtn->move(25 + i % 4 * 70, 130 + i / 4 * 70);

    // 监听每隔按钮的点击事件
    connect(menuBtn, &MyPushButton::clicked, [=](){
        QString str = QString("您选择的是第%1关").arg(i + 1);
        qDebug() << str;
    });

    QLabel *label = new QLabel;
    label->setParent(this);
    label->setFixedSize(menuBtn->width(), menuBtn->height());
    label->setText(QString::number(i + 1));
    label->move(25 + i % 4 * 70, 130 + i / 4 * 70);

    // 设置label上的文字对齐方式 水平居中和垂直居中
    label->setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
    // 设置让鼠标进行穿透51号属性
    label->setAttribute(Qt::WA_TransparentForMouseEvents);
}

四、翻金币的场景 

4.1 创建类

QT学习日记22——翻金币游戏_第34张图片

4.2 选择关卡场景中添加关卡 

QT学习日记22——翻金币游戏_第35张图片

QT学习日记22——翻金币游戏_第36张图片

重新写一个构造函数

QT学习日记22——翻金币游戏_第37张图片

QT学习日记22——翻金币游戏_第38张图片

4.3 游戏场景中的配置

添加头文件  #include

QT学习日记22——翻金币游戏_第39张图片

#include "playscene.h"

PlayScene::PlayScene(int levelNum)
{
    this->levelIndex = levelNum;

    // 初始化游戏场景
    // 设置固定大小
    this->setFixedSize (320,588) ;
    //设置图标
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    //设置标题
    this->setWindowTitle("翻金币场景");

    // 创建菜单栏
    QMenuBar *menubar= menuBar();
    setMenuBar(menubar);
    // 创建开始菜单
    QMenu *menuStart = menubar->addMenu("开始");
    // 创建退出菜单项
    QAction *actionQuit = menuStart->addAction("退出");
    // 点击退出实现退出游戏
    connect(actionQuit, &QAction::triggered, [=](){
        this->close();
    });
}

重写绘图事件,添加头文件  #include

QT学习日记22——翻金币游戏_第40张图片

void PlayScene::paintEvent(QPaintEvent *)
{
    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);  // 宽高变成原来的0.5
    painter.drawPixmap(10, 30, pix.width(), pix.height(), pix);
}

4.4 游戏场景返回到选择关卡

先添加自定义按钮的头文件 #include "mypushbutton.h"

添加信号:

QT学习日记22——翻金币游戏_第41张图片

点击后发送信号

QT学习日记22——翻金币游戏_第42张图片

在游戏选择场景中监听发送的信号,如果返回到这个场景就删除创建的游戏

QT学习日记22——翻金币游戏_第43张图片

    // 创建选择关卡的按钮
    for(int i = 0; i < 20; i++) {
        MyPushButton *menuBtn = new MyPushButton(":/res/LevelIcon.png");
        menuBtn->setParent(this);
        menuBtn->move(25 + i % 4 * 70, 130 + i / 4 * 70);

        // 监听每隔按钮的点击事件
        connect(menuBtn, &MyPushButton::clicked, [=](){
            QString str = QString("您选择的是第%1关").arg(i + 1);
            qDebug() << str;

            // 进入到游戏场景
            this->hide();  // 将选关场景隐藏掉
            play = new PlayScene(i + 1);  // 创建游戏场景
            play->show();  // 显示游戏场景

            connect(play, &PlayScene::chooseSceneBack, [=](){
                this->show();
                delete play;
                play = nullptr;
            });
        });

        QLabel *label = new QLabel;
        label->setParent(this);
        label->setFixedSize(menuBtn->width(), menuBtn->height());
        label->setText(QString::number(i + 1));
        label->move(25 + i % 4 * 70, 130 + i / 4 * 70);

        // 设置label上的文字对齐方式 水平居中和垂直居中
        label->setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
        // 设置让鼠标进行穿透51号属性
        label->setAttribute(Qt::WA_TransparentForMouseEvents);
    }

4.5 显示当前关卡数

添加头文件 #include

QT学习日记22——翻金币游戏_第44张图片

    // 显示当前关卡数
    QLabel *label = new QLabel;
    label->setParent(this);
    QFont font;
    font.setFamily("黑体");
    font.setPointSize(20);
    QString str1 = QString("Level:%1").arg(this->levelIndex);
    qDebug() << str1;
    //将字体设置到标签控件中
    label->setFont(font);
    label->setText(str1);
    label->setGeometry(30, this->height() - 50, 140, 50);

4.6 显示金币背景图案

QT学习日记22——翻金币游戏_第45张图片

// 显示金币背景图案
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);
    }
}

五、翻转金币

5.1 金币类

QT学习日记22——翻金币游戏_第46张图片

QT学习日记22——翻金币游戏_第47张图片

QT学习日记22——翻金币游戏_第48张图片

#include "mycoin.h"

MyCoin::MyCoin(QString btnImg)
{
    QPixmap pix;
    bool ret = pix.load(btnImg);
    if(!ret)
    {
        QString str = QString("图片 %1 加载失败").arg(btnImg);
        qDebug() << str;
        return;
    }

    // 设置图片固定大小
    this->setFixedSize(pix.width(), pix.height());
    // 设置不规则图片样式
    this->setStyleSheet("QPushButton{border:0px;}");
    // 设置图标
    this->setIcon(pix);
    // 设置图标大小
    this->setIconSize(QSize(pix.width(), pix.height()));
}

5.2 游戏场景中包含金币 

QT学习日记22——翻金币游戏_第49张图片

QT学习日记22——翻金币游戏_第50张图片

5.3 初始化金币银币数据

把配置文件弄进来

QT学习日记22——翻金币游戏_第51张图片

 右键添加现有文件

QT学习日记22——翻金币游戏_第52张图片

包含头文件,然后新加一个二维数组 

QT学习日记22——翻金币游戏_第53张图片

创建游戏界面的时候初始化二维数组

QT学习日记22——翻金币游戏_第54张图片

初始化金币

QT学习日记22——翻金币游戏_第55张图片

    dataConfig config;
    // 初始化每个关卡的二维数组
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            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, 157 + 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(60 + i * 50, 160 + j * 50);
        }
    }

5.4 金币翻转特效实现

添加金币属性

QT学习日记22——翻金币游戏_第56张图片

QT学习日记22——翻金币游戏_第57张图片

金币来回翻转的效果(类似于 gif 一帧一帧播放)

QT学习日记22——翻金币游戏_第58张图片

QT学习日记22——翻金币游戏_第59张图片

#include "mycoin.h"

MyCoin::MyCoin(QString btnImg)
{
    QPixmap pix;
    bool ret = pix.load(btnImg);
    if(!ret)
    {
        QString str = QString("图片 %1 加载失败").arg(btnImg);
        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;
            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()));
        // 判断 如果翻完了,将max重置为8
        if(this->max < this->min)
        {
            this->max = 8;
            timer2->stop();
        }
    });
}

// 改变金银币标志的方法
void MyCoin::changeFlag()
{
    // 如果是正面 翻成反面
    if(this->flag)
    {
        // 开始正面翻方面的定时器
        timer1->start(30);
        this->flag = false;
    }
    else // 银币翻金币
    {
        timer2->start(30);
        this->flag = true;
    }

}

QT学习日记22——翻金币游戏_第60张图片

中间有一些bug,例如动画没有播放完就点了,我们可以限制一下

QT学习日记22——翻金币游戏_第61张图片

 QT学习日记22——翻金币游戏_第62张图片

 QT学习日记22——翻金币游戏_第63张图片

 QT学习日记22——翻金币游戏_第64张图片

QT学习日记22——翻金币游戏_第65张图片

5.5 翻转周围的金币

QT学习日记22——翻金币游戏_第66张图片

将创建好的金币放入数组用于维护,并作翻转

QT学习日记22——翻金币游戏_第67张图片 

    // 显示金币背景图案
    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, 157 + 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(60 + i * 50, 160 + j * 50);

            // 给金币属性赋值
            coin->posX = i;
            coin->posY = j;
            coin->flag = this->gameArray[i][j];  // 1金币 0银币

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

            // 点击金、银币进行翻转
            connect(coin, &MyCoin::clicked, [=](){
               coin->changeFlag();
               this->gameArray[i][j] = !this->gameArray[i][j];

               // 翻转周围硬币
               if(coin->posX + 1 <= 3) // 金币的右侧金币翻转条件
               {
                   coinBtn[coin->posX + 1][coin->posY]->changeFlag();
                   this->gameArray[coin->posX + 1][coin->posY] = !this->gameArray[coin->posX + 1][coin->posY];
               }
               if(coin->posX - 1 >= 0) // 金币的左侧金币翻转条件
               {
                   coinBtn[coin->posX - 1][coin->posY]->changeFlag();
                   this->gameArray[coin->posX - 1][coin->posY] = !this->gameArray[coin->posX - 1][coin->posY];
               }
               if(coin->posY + 1 <= 3) // 金币的上侧金币翻转条件
               {
                   coinBtn[coin->posX][coin->posY + 1]->changeFlag();
                   this->gameArray[coin->posX][coin->posY + 1] = !this->gameArray[coin->posX][coin->posY + 1];
               }
               if(coin->posY - 1 >= 0) // 金币的下侧金币翻转条件
               {
                   coinBtn[coin->posX][coin->posY - 1]->changeFlag();
                   this->gameArray[coin->posX][coin->posY - 1] = !this->gameArray[coin->posX][coin->posY - 1];
               }
            });
        }
    }

5.7 周围延时翻转

QT学习日记22——翻金币游戏_第68张图片

 

六、胜利处理

6.1 胜利判断并禁用按钮

QT学习日记22——翻金币游戏_第69张图片

 QT学习日记22——翻金币游戏_第70张图片

 

QT学习日记22——翻金币游戏_第71张图片

如果胜利了,所有的银币按钮的标志位都改成游戏胜利 

QT学习日记22——翻金币游戏_第72张图片

 

// 翻转周围硬币
               // 周围延时翻转
               QTimer::singleShot(300, this, [=](){
                   if(coin->posX + 1 <= 3) // 金币的右侧金币翻转条件
                   {
                       coinBtn[coin->posX + 1][coin->posY]->changeFlag();
                       this->gameArray[coin->posX + 1][coin->posY] = !this->gameArray[coin->posX + 1][coin->posY];
                   }
                   if(coin->posX - 1 >= 0) // 金币的左侧金币翻转条件
                   {
                       coinBtn[coin->posX - 1][coin->posY]->changeFlag();
                       this->gameArray[coin->posX - 1][coin->posY] = !this->gameArray[coin->posX - 1][coin->posY];
                   }
                   if(coin->posY + 1 <= 3) // 金币的上侧金币翻转条件
                   {
                       coinBtn[coin->posX][coin->posY + 1]->changeFlag();
                       this->gameArray[coin->posX][coin->posY + 1] = !this->gameArray[coin->posX][coin->posY + 1];
                   }
                   if(coin->posY - 1 >= 0) // 金币的下侧金币翻转条件
                   {
                       coinBtn[coin->posX][coin->posY - 1]->changeFlag();
                       this->gameArray[coin->posX][coin->posY - 1] = !this->gameArray[coin->posX][coin->posY - 1];
                   }

                   // 判断是否胜利
                   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)
                   {
                       for(int i = 0; i < 4;i ++)
                       {
                           for(int j = 0; j < 4; j++)
                           {
                               coinBtn[i][j]->isWin = true;
                           }
                       }
                   }
               });

已经胜利就屏蔽点击,下图已经是点击不了了

QT学习日记22——翻金币游戏_第73张图片

 

6.2 胜利图片实现

已经创建了图片,但是在屏幕的上方,我们在后面写一个函数,用于这个胜利的图片掉下来的效果i哦

QT学习日记22——翻金币游戏_第74张图片

 

    // 胜利图像绘制
    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());

加入头文件 #include

QT学习日记22——翻金币游戏_第75张图片

// 将胜利的图片从上往下移动
QPropertyAnimation *animation = new QPropertyAnimation(winLabel, "geometry");
// 设置时间间隔
animation->setDuration(1000);
// 设置开始位置
animation->setStartValue(QRect(winLabel->x(), winLabel->y(), winLabel->width(), winLabel->height()));
// 设置结束位置
animation->setEndValue(QRect(winLabel->x(), winLabel->y() + 134, winLabel->width(), winLabel->height()));
// 设置曲线
animation->setEasingCurve(QEasingCurve::OutBounce);
// 执行动画
animation->start();

6.3 优化一些内容

1、通关后不能再点击,这是因为硬币 isWin 含有初始值为 true,我们可以在构造函数的时候设置硬币的游戏是否胜利为 false

QT学习日记22——翻金币游戏_第76张图片

 

2、手速快出问题了,因为只禁用了一个按钮

QT学习日记22——翻金币游戏_第77张图片

解决方案是先把所有按钮禁用了

QT学习日记22——翻金币游戏_第78张图片

等完成动画后再开启所有按钮 

QT学习日记22——翻金币游戏_第79张图片

 

6.5 设置音效

增加多媒体模块

QT学习日记22——翻金币游戏_第80张图片

包含头文件

QT学习日记22——翻金币游戏_第81张图片

QT学习日记22——翻金币游戏_第82张图片

QT学习日记22——翻金币游戏_第83张图片

QT学习日记22——翻金币游戏_第84张图片

后面的和前面类似处理,

选择关卡音效

QT学习日记22——翻金币游戏_第85张图片

QT学习日记22——翻金币游戏_第86张图片

游戏关卡音效

QT学习日记22——翻金币游戏_第87张图片

 QT学习日记22——翻金币游戏_第88张图片

QT学习日记22——翻金币游戏_第89张图片

音乐可以循环播放, Qsound 对象里面有 setLoops(10) 这个方法,设置为循环 10 次,也可以 setLoops(-1) 无限循环

七、优化和发布

7.1 在每个场景中都保持在一个位置

 因为每次切换场景,如果移动了窗口,新的窗口所在的位置和原来的窗口可能不同

QT学习日记22——翻金币游戏_第90张图片

 QT学习日记22——翻金币游戏_第91张图片

 QT学习日记22——翻金币游戏_第92张图片

7.2 打包发布

QT学习日记22——翻金币游戏_第93张图片

QT学习日记22——翻金币游戏_第94张图片

 QT学习日记22——翻金币游戏_第95张图片

 

 QT学习日记22——翻金币游戏_第96张图片

 后面可以用其他的打包软件(就是变成压缩包,别人下载后解压用的)

你可能感兴趣的:(QT,学习,游戏)