QT翻金币小游戏(含音频图片文件资源)

news2024/9/22 3:33:15

目录

QT翻金币小游戏

音频图片资源文件获取

效果展示

图片

视频

实现代码

main.cpp

 mymainwindow.h

mymainwindow.cpp

 startscene.h

startscene.cpp

selectscene.cpp

playscene.h

playscene.cpp

 mypushbutton.h

 mypushbutton.cpp

dataconfig.h

dataconfig.cpp


QT翻金币小游戏

音频图片资源文件获取

通过百度网盘分享的文件:音频与图片资源
链接:https://pan.baidu.com/s/1GvZl3YaNG-Fl11Hi0rk6WQ 
提取码:coin

效果展示

图片

 

视频

QT翻金币

实现代码

main.cpp

#include "mymainwindow.h"  // 引入自定义的 MyMainWindow 类头文件
#include "startscene.h"    // 引入自定义的 StartScene 类头文件

#include <QApplication>    // 引入 Qt 应用程序类的头文件

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);  // 创建 QApplication 对象,初始化应用程序,处理命令行参数

    StartScene sc;               // 创建 StartScene 对象,作为应用程序的主场景或窗口
    sc.show();                   // 显示 StartScene 对象,即显示窗口

    return a.exec();             // 进入 Qt 事件循环,等待并处理事件
}

 mymainwindow.h

#ifndef MYMAINWINDOW_H  // 如果没有定义 MYMAINWINDOW_H
#define MYMAINWINDOW_H  // 定义 MYMAINWINDOW_H,防止头文件被多次包含

#include <QMainWindow>  // 引入 QMainWindow 类
#include <QSoundEffect>  // 引入 QSoundEffect 类用于播放声音
#include <QUrl>  // 引入 QUrl 类用于处理 URL
#include <QCoreApplication>  // 引入 QCoreApplication 类用于应用程序的核心功能

QT_BEGIN_NAMESPACE  // 开始 Qt 命名空间

namespace Ui {
class MyMainWindow;  // 前向声明 Ui::MyMainWindow 类
}

QT_END_NAMESPACE  // 结束 Qt 命名空间

class MyMainWindow : public QMainWindow  // 定义 MyMainWindow 类,继承自 QMainWindow
{
    Q_OBJECT  // 使得类可以使用 Qt 的信号和槽机制

public:
    MyMainWindow(QWidget *parent = nullptr);  // 构造函数,接受一个可选的父窗口参数
    ~MyMainWindow();  // 析构函数

    void playSoundEffect(const QString& filePath);  // 声明播放声音效果的成员函数

protected:
    void paintEvent(QPaintEvent *event);  // 声明绘制事件的重写函数

private:
    Ui::MyMainWindow *ui;  // 指向自动生成的 UI 类的指针
};

#endif // MYMAINWINDOW_H  // 结束头文件保护宏

mymainwindow.cpp

#include "mymainwindow.h"  // 引入自定义的 MyMainWindow 类头文件
#include "./ui_mymainwindow.h"  // 引入自动生成的 UI 文件头文件
#include <QPainter>  // 引入 Qt 的绘图类头文件

MyMainWindow::MyMainWindow(QWidget *parent)
    : QMainWindow(parent)  // 调用基类 QMainWindow 的构造函数
    , ui(new Ui::MyMainWindow)  // 初始化 UI 对象
{
    ui->setupUi(this);  // 设置 UI 组件

    ui->actionQuit->setIcon(QIcon(":/image/Quit.png"));  // 为“退出”动作设置图标
    this->setWindowIcon(QPixmap(":/image/Coin0001.png"));  // 设置主窗口图标
    this->setWindowTitle("翻金币小游戏");  // 设置主窗口标题
    this->setFixedSize(320,588);  // 设置窗口固定大小,宽320高588
}

MyMainWindow::~MyMainWindow()
{
    delete ui;  // 删除 UI 对象以释放内存
}

void MyMainWindow::playSoundEffect(const QString &filePath)
{
    QSoundEffect *sound = new QSoundEffect;  // 创建 QSoundEffect 对象
    sound->setSource(QUrl::fromLocalFile(filePath));  // 设置音频文件路径
    sound->setVolume(0.5f);  // 可选:设置音量为 0.5
    sound->play();  // 播放声音
    // 连接信号槽,当播放完成时自动删除对象
    QObject::connect(sound, &QSoundEffect::playingChanged, [sound]() {
        if (!sound->isPlaying()) {
            delete sound;  // 播放完成后删除声音对象
        }
    });
}

void MyMainWindow::paintEvent(QPaintEvent *event)
{
    // 绘制背景图片
    QPainter painter(this);  // 创建 QPainter 对象用于绘图
    painter.translate(0,this->menuBar()->height());  // 将画家的原点移动到菜单栏下方
    QPixmap pix(":/image/MenuSceneBg.png");  // 加载背景图片
    painter.drawPixmap(0, 0, this->width(), this->height(), pix);  // 绘制背景图,填充整个窗口
}

 startscene.h

#ifndef STARTSCENE_H  // 检查是否未定义 STARTSCENE_H
#define STARTSCENE_H  // 定义 STARTSCENE_H,避免头文件重复包含

#include <QMainWindow>  // 引入 QMainWindow 类
#include "mymainwindow.h"  // 引入 MyMainWindow 类的头文件
#include "selectscene.h"  // 引入 SelectScene 类的头文件

class StartScene : public MyMainWindow  // StartScene 类继承自 MyMainWindow
{
    Q_OBJECT  // 使 StartScene 类成为 Qt 的对象模型的一部分,支持信号和槽机制
public:
    explicit StartScene(QWidget *parent = nullptr);  // 构造函数声明,接受一个可选的父窗口指针
private:
    SelectScene msc;  // 定义一个 SelectScene 类型的成员变量 msc
signals:
};

#endif // STARTSCENE_H  // 结束条件编译,确保此头文件只被包含一次

startscene.cpp

#include "startscene.h"  // 引入 StartScene 头文件
#include "mypushbutton.h"  // 引入 MyPushButton 头文件
#include <QTimer>  // 引入 QTimer 类用于定时操作
#include <QSoundEffect>  // 引入 QSoundEffect 类用于播放声音效果

StartScene::StartScene(QWidget *parent)
    : MyMainWindow{parent}  // 调用基类 MyMainWindow 的构造函数
{
    // 开始按钮
    MyPushButton *btnStart = new MyPushButton(":/image/MenuSceneStartButton.png",
                                              ":/image/MenuSceneStartButton.png",
                                              this);  // 创建 MyPushButton 对象,并设置图片和父窗口
    btnStart->resize(114,114);  // 设置按钮的尺寸
    btnStart->move(this->width()/2-btnStart->width()/2,  // 将按钮水平居中
                   this->height()*3/4-btnStart->height()/2);  // 将按钮垂直位置设置为窗口高度的三分之四

    connect(btnStart, &MyPushButton::clicked, [=](){  // 连接按钮的 clicked 信号到槽函数
        this->playSoundEffect(":/music/TapButtonSound.wav");  // 播放按钮点击声音
        btnStart->setEnabled(false);  // 禁用按钮
        btnStart->moveDown();  // 执行下跳动画
        QTimer::singleShot(150, [=](){  // 在 150ms 后执行
            btnStart->moveUp();  // 执行上跳动画
        });
        QTimer::singleShot(300, [=](){  // 在 300ms 后执行
            btnStart->setEnabled(true);  // 启用按钮
            // 场景转换
            this->msc.move(this->pos());  // 移动 SelectScene 到当前窗口位置
            this->msc.show();  // 显示 SelectScene
            this->hide();  // 隐藏当前窗口
        });
    });

    connect(&this->msc, &SelectScene::backBtnClicked, [=](){  // 连接 SelectScene 的 backBtnClicked 信号到槽函数
        this->playSoundEffect(":/music/BackButtonSound.wav");  // 播放返回按钮声音
        this->move(this->msc.pos());  // 移动当前窗口到 SelectScene 的位置
        this->show();  // 显示当前窗口
        this->msc.hide();  // 隐藏 SelectScene
    });
}

 selectscene.h

#ifndef SELECTSCENE_H  // 检查是否未定义 SELECTSCENE_H
#define SELECTSCENE_H  // 定义 SELECTSCENE_H,避免头文件重复包含

#include <QMainWindow>  // 引入 QMainWindow 类
#include "mymainwindow.h"  // 引入 MyMainWindow 类的头文件

class SelectScene : public MyMainWindow  // SelectScene 类继承自 MyMainWindow
{
    Q_OBJECT  // 使 SelectScene 类成为 Qt 的对象模型的一部分,支持信号和槽机制
public:
    explicit SelectScene(QWidget *parent = nullptr);  // 构造函数声明,接受一个可选的父窗口指针

protected:
    void paintEvent(QPaintEvent *event);  // 声明重写的 paintEvent 方法,用于绘制界面

signals:
    void backBtnClicked();  // 声明信号 backBtnClicked,当点击back按钮事件时信号发出
};

#endif // SELECTSCENE_H  // 结束条件编译,确保此头文件只被包含一次

selectscene.cpp

#include "selectscene.h"  // 引入 SelectScene 类的头文件
#include <QPushButton>  // 引入 QPushButton 类
#include <QPainter>  // 引入 QPainter 类,用于绘图
#include "./ui_mymainwindow.h"  // 引入 MyMainWindow 的用户界面头文件
#include "mypushbutton.h"  // 引入 MyPushButton 类的头文件
#include "playscene.h"  // 引入 PlayScene 类的头文件

// SelectScene 的构造函数
SelectScene::SelectScene(QWidget *parent)
    : MyMainWindow{parent}  // 调用基类构造函数,初始化 parent
{
    this->setWindowTitle("选择关卡");  // 设置窗口标题为 "选择关卡"

    // 创建返回按钮
    MyPushButton *btnBack = new MyPushButton(":/image/BackButton.png",
                                             ":/image/BackButtonSelected.png",
                                             this);
    btnBack->resize(72, 32);  // 设置按钮大小
    btnBack->move(this->width() - btnBack->width(),  // 设置按钮位置,使其靠右下角
                  this->height() - btnBack->height());

    // 连接返回按钮的点击信号到 backBtnClicked 槽
    connect(btnBack, &QPushButton::clicked, this, &SelectScene::backBtnClicked);

    // 设置每个关卡按钮的尺寸和位置参数
    const int colwidth = 70;  // 列宽
    const int rowheight = 70;  // 行高
    const int xoffset = 25;  // X 偏移量
    const int yoffset = 130;  // Y 偏移量

    // 创建 20 个关卡按钮
    for(int i = 0; i < 20; i++){
        MyPushButton *btn = new MyPushButton(":/image/LevelIcon.png", ":/image/LevelIcon.png", this);
        btn->setText(QString::number(i + 1));  // 设置按钮上的文本为关卡号
        int col = i % 4;  // 计算列索引
        int row = i / 4;  // 计算行索引
        int x = col * colwidth + xoffset;  // 计算按钮的 X 坐标
        int y = row * rowheight + yoffset;  // 计算按钮的 Y 坐标
        btn->resize(57, 57);  // 设置按钮大小
        btn->move(x, y);  // 设置按钮位置

        // 连接按钮的点击信号到一个 lambda 表达式
        connect(btn, &MyPushButton::clicked, [=](){
            this->playSoundEffect(":/music/TapButtonSound.wav");  // 播放点击按钮的声音
            PlayScene *ps = new PlayScene(i + 1);  // 创建一个新的 PlayScene 实例
            ps->setAttribute(Qt::WA_DeleteOnClose);  // 设置属性,确保关闭时自动删除
            ps->move(this->pos());  // 将 PlayScene 窗口移动到当前窗口的位置
            ps->show();  // 显示 PlayScene 窗口
            this->hide();  // 隐藏当前窗口

            // 连接 PlayScene 的 backBtnClicked 信号到一个 lambda 表达式
            connect(ps, &PlayScene::backBtnClicked, [=](){
                this->playSoundEffect(":/music/BackButtonSound.wav");  // 播放返回按钮的声音
                this->move(ps->pos());  // 将当前窗口移动到 PlayScene 窗口的位置
                this->show();  // 显示当前窗口
                ps->close();  // 关闭 PlayScene 窗口
            });
        });
    }
}

// 重写 paintEvent 方法,用于自定义绘图
void SelectScene::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);  // 创建 QPainter 对象
    painter.translate(0, this->menuBar()->height());  // 移动画家到菜单栏下面

    QPixmap pix(":/image/OtherSceneBg.png");  // 加载背景图片
    painter.drawPixmap(0, 0, this->width(), this->height(), pix);  // 绘制背景图片

    pix.load(":/image/Title.png");  // 加载标题图片
    painter.drawPixmap(0, 0, pix);  // 绘制标题图片
}

playscene.h

#ifndef PLAYSCENE_H
#define PLAYSCENE_H

#include <QMainWindow>  // 引入 QMainWindow 类
#include "mymainwindow.h"  // 引入 MyMainWindow 类
#include "coinbutton.h"  // 引入 CoinButton 类

class PlayScene : public MyMainWindow  // PlayScene 继承自 MyMainWindow
{
    Q_OBJECT  // 使 PlayScene 成为 Qt 对象,支持信号和槽机制
public:
    PlayScene(int level, QWidget *parent = nullptr);  // 构造函数,接受关卡数和父窗口指针

    void flip(int row, int col);  // 翻转指定位置的硬币
    void judgeWin();  // 判断是否赢得游戏

protected:
    void paintEvent(QPaintEvent *event);  // 重写 paintEvent 方法,用于自定义绘图

signals:
    void backBtnClicked();  // 声明返回按钮点击的信号

private:
    CoinButton *mCoins[4][4];  // 4x4 硬币按钮数组
    bool winFlag;  // 游戏胜利标志
};

#endif // PLAYSCENE_H

playscene.cpp

#include "playscene.h" // 包含 PlayScene 类的头文件
#include "mypushbutton.h" // 包含 MyPushButton 类的头文件
#include "./ui_mymainwindow.h" // 包含 MyMainWindow 的 UI 头文件
#include <QPainter> // 包含 QPainter 用于绘制
#include <QLabel> // 包含 QLabel 用于文本显示
#include "coinbutton.h" // 包含 CoinButton 类
#include "dataconfig.h" // 包含 DataConfig 类
#include <QTimer> // 包含 QTimer 用于定时事件
#include <QPropertyAnimation> // 包含 QPropertyAnimation 用于动画

PlayScene::PlayScene(int level, QWidget *parent) // PlayScene 构造函数
    : MyMainWindow{parent} // 初始化基类 MyMainWindow
{
    winFlag = false; // 初始化 winFlag 为 false 失败

    this->setWindowTitle(QString("关卡%1").arg(level)); // 设置窗口标题为当前关卡几
    MyPushButton *btnBack = new MyPushButton(":/image/BackButton.png", 
                                             ":/image/BackButtonSelected.png",
                                             this); // 设置第一张图为未按下时的状态,第二张图为按下时的状态,父级为当前窗口
    btnBack->resize(72,32); // 设置返回按钮的大小
    btnBack->move(this->width()-btnBack->width(), 
                  this->height()-btnBack->height());// 将返回按钮移动到右下角

    connect(btnBack,&QPushButton::clicked,this,&PlayScene::backBtnClicked); // 连接返回按钮的点击信号到 backBtnClicked 槽

    QLabel *label = new QLabel(this); // 创建一个 QLabel 显示关卡信息
    label->resize(150,50); // 设置标签的大小
    label->setText(QString("Level:%1").arg(level)); // 设置标签文本为当前关卡几
    label->setFont(QFont("华文新魏",20)); // 设置标签字体和大小
    label->move(30,this->height()-label->height()); // 将标签移动到底部左侧

    const int colwidth = 50; // 每列的宽度
    const int rowheight = 50; // 每行的高度
    const int xoffset = 57; // 硬币按钮的 x 偏移量
    const int yoffset = 200; // 硬币按钮的 y 偏移量

    dataConfig data; // 创建 dataConfig 对象
    QVector <QVector <int >> dataArray = data.mData[level]; // 获取当前关卡的数据

    for(int row = 0; row < 4; row ++) // 遍历行
    {
        for(int col = 0; col < 4; col ++) // 遍历列
        {
            CoinButton *btn = new CoinButton(this); // 创建新的 CoinButton
            mCoins[row][col] = btn; // 将按钮存储在 mCoins 数组中
            int x = col * colwidth + xoffset; // 计算 x 位置
            int y = row * rowheight + yoffset; // 计算 y 位置
            btn->setGeometry(x,y,50,50); // 设置按钮的大小和位置
            btn->setMstat(dataArray[row][col]); // 根据数据设置金币状态1为金币0为银币

            connect(btn,&CoinButton::clicked,[=](){ // 连接按钮点击信号到 flip 函数
                this->flip(row,col); // 调用 flip 函数处理金币翻转
            });
        }
    }
}

void PlayScene::flip(int row, int col) // 处理硬币翻转的函数
{
    if(winFlag) // 如果已经赢了
        return; // 直接结束函数
    this->mCoins[row][col]->flip(); // 翻转点击位置的硬币
    this->playSoundEffect(":/music/ConFlipSound.wav"); // 播放翻转音效
    QTimer::singleShot(250,[=](){ // 250ms后翻转相邻的硬币
        if(row + 1 < 4) // 检查下方是否有硬币
            this->mCoins[row + 1][col]->flip(); // 翻转下方的硬币
        if(row - 1 >= 0) // 检查上方是否有硬币
            this->mCoins[row - 1][col]->flip(); // 翻转上方的硬币
        if(col - 1 >= 0) // 检查左侧是否有硬币
            this->mCoins[row][col - 1]->flip(); // 翻转左侧的硬币
        if(col + 1 < 4) // 检查右侧是否有硬币
            this->mCoins[row][col + 1]->flip(); // 翻转右侧的硬币
        this->judgeWin(); // 判断是否胜利
    });
}

void PlayScene::judgeWin() // 判断是否完成关卡
{
    for(int row = 0; row < 4; row ++) // 遍历行
    {
        for(int col = 0; col < 4; col ++) // 遍历列
        {
            if(!this->mCoins[row][col]->getMstat()) // 如果有银币不是胜利状态
                return ; // 直接结束函数
        }
    }
    winFlag = true; // 设置 winFlag 为 true 胜利
    this->playSoundEffect(":/music/LevelWinSound.wav"); // 播放胜利音效
    QLabel *labelWin = new QLabel(this); // 创建 QLabel 显示胜利信息
    QPixmap pix = QPixmap(":/image/LevelCompletedDialogBg.png"); // 加载胜利对话框图片
    labelWin->setPixmap(pix); // 设置标签的图片
    labelWin->resize(pix.size()); // 设置标签的大小
    labelWin->show(); // 显示胜利信息
    labelWin->move(this->width()/2-labelWin->width()/2,-labelWin->height()); // 初始位置设在屏幕外

    QPropertyAnimation *animation = new QPropertyAnimation(labelWin, "geometry",this); // 创建胜利标签动画
    animation->setStartValue(labelWin->geometry());  // 设置动画的起始位置
    animation->setEndValue(QRect(labelWin->x(),  labelWin->y()+180,  labelWin->width(), labelWin->height())); // 设置动画的结束位置
    animation->setDuration(1000);  // 设置动画的持续时间
    animation->setEasingCurve(QEasingCurve::OutBounce); // 设置动画的缓动曲线
    animation->start(QPropertyAnimation::DeleteWhenStopped); // 启动动画并在结束时删除
}

void PlayScene::paintEvent(QPaintEvent *event) // 重写 paintEvent 绘制自定义元素
{
    QPainter painter(this); // 创建 QPainter 对象用于绘制
    painter.translate(0,this->menuBar()->height()); // 移动绘制区域到菜单栏下方
    QPixmap pix(":/image/PlayLevelSceneBg.png"); // 加载背景图片
    painter.drawPixmap(0, 0, this->width(), this->height(), pix); // 绘制背景图片填充整个窗口
    pix.load(":/image/Title.png"); // 加载logo图片
    pix = pix.scaled(pix.width()/2,pix.height()/2); // 缩放logo图片50%
    painter.drawPixmap(0,0,pix); // 在窗口左上角绘制标题图片
}

 mypushbutton.h

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

#include <QWidget> // 引入 QWidget 头文件,用于继承 QWidget
#include <QPushButton> // 引入 QPushButton 头文件,用于继承 QPushButton

class MyPushButton : public QPushButton // 定义 MyPushButton 类,继承自 QPushButton
{
    Q_OBJECT // 宏,启用 Qt 的信号与槽机制
public:
    enum MyPushButtonStat // 定义枚举类型 MyPushButtonStat,用于按钮状态
    {
        NORMAL, // 正常状态
        PRESSED // 按下状态
    };
    MyPushButton(QString normalImg, QString pressedImg, QWidget *parent = nullptr); // 构造函数声明,接受正常和按下状态的图片路径,以及父级 widget
    void moveDown(); // 移动按钮向下的函数声明
    void moveUp(); // 移动按钮向上的函数声明

protected:
    void paintEvent(QPaintEvent *event); // 重写 paintEvent 函数,用于自定义绘制
    void mousePressEvent(QMouseEvent *e); // 重写 mousePressEvent 函数,用于处理鼠标按下事件
    void mouseReleaseEvent(QMouseEvent *e); // 重写 mouseReleaseEvent 函数,用于处理鼠标释放事件

signals:

private:
    QString mNormalImg; // 存储正常状态图片路径
    QString mPressedImg; // 存储按下状态图片路径
    MyPushButtonStat mStat; // 存储当前按钮状态
};

#endif // MYPUSHBUTTON_H

 mypushbutton.cpp

#include "mypushbutton.h" // 引入自定义按钮类的头文件
#include <QPainter> // 引入 QPainter 头文件,用于绘图
#include <QPropertyAnimation> // 引入 QPropertyAnimation 头文件,用于动画效果

// 构造函数,初始化按钮的正常图片和按下图片路径
MyPushButton::MyPushButton(QString normalImg, QString pressedImg, QWidget *parent)
    : QPushButton{parent} // 调用基类 QPushButton 的构造函数
    , mNormalImg(normalImg) // 初始化正常状态图片路径
    , mPressedImg(pressedImg) // 初始化按下状态图片路径
{
    mStat = NORMAL; // 设置按钮的初始状态为正常状态
}

// 动画下跳
void MyPushButton::moveDown()
{
    QPropertyAnimation *animation = new QPropertyAnimation(this, "geometry", this); // 创建动画对象,作用于按钮的几何属性
    animation->setStartValue(this->geometry()); // 设置动画起始位置为当前按钮位置
    animation->setEndValue(QRect(this->x(), this->y() + 10, this->width(), this->height())); // 设置动画结束位置为下移10像素后的按钮位置
    animation->setDuration(100); // 设置动画持续时间为100毫秒
    animation->start(QPropertyAnimation::DeleteWhenStopped); // 动画结束后自动删除
}

// 动画上跳
void MyPushButton::moveUp()
{
    QPropertyAnimation *animation = new QPropertyAnimation(this, "geometry", this); // 创建动画对象,作用于按钮的几何属性
    animation->setStartValue(this->geometry()); // 设置动画起始位置为当前按钮位置
    animation->setEndValue(QRect(this->x(), this->y() - 10, this->width(), this->height())); // 设置动画结束位置为上移10像素后的按钮位置
    animation->setDuration(100); // 设置动画持续时间为100毫秒
    animation->start(QPropertyAnimation::DeleteWhenStopped); // 动画结束后自动删除
}

void MyPushButton::paintEvent(QPaintEvent *event)
{
    // 绘制按钮图片
    QPainter painter(this); // 创建绘图对象
    QPixmap pix; // 创建 QPixmap 对象,用于加载图片
    if (mStat == NORMAL) // 判断当前状态是否为正常
        pix.load(mNormalImg); // 加载正常状态的图片
    if (mStat == PRESSED) // 判断当前状态是否为按下
        pix.load(mPressedImg); // 加载按下状态的图片
    painter.drawPixmap(0, 0, this->width(), this->height(), pix); // 绘制图片
    painter.drawText(0, 0, this->width(), this->height(), // 绘制文本
                     Qt::AlignCenter | Qt::AlignVCenter, // 文本居中对齐
                     this->text()); // 绘制按钮上的文本
}

void MyPushButton::mousePressEvent(QMouseEvent *e)
{
    this->mStat = PRESSED; // 设置按钮状态为按下
    update(); // 触发重绘事件以更新按钮外观
    QPushButton::mousePressEvent(e); // 调用基类的鼠标按下事件处理函数
}

void MyPushButton::mouseReleaseEvent(QMouseEvent *e)
{
    this->mStat = NORMAL; // 设置按钮状态为正常
    update(); // 触发重绘事件以更新按钮外观
    QPushButton::mouseReleaseEvent(e); // 调用基类的鼠标释放事件处理函数
}

 coinbutton.h

#ifndef COINBUTTON_H // 如果没有定义 COINBUTTON_H,则继续编译
#define COINBUTTON_H // 定义 COINBUTTON_H,防止重复包含

#include <QWidget> // 引入 QWidget 基类
#include <QPushButton> // 引入 QPushButton 类
#include <QTimer> // 引入 QTimer 类

class CoinButton : public QPushButton // 定义 CoinButton 类,继承自 QPushButton
{
    Q_OBJECT // 使用 Qt 的信号和槽机制

public:
    explicit CoinButton(QWidget *parent = nullptr); // 构造函数,接收父窗口指针

    int getMstat() const; // 获取当前状态
    void setMstat(int newMstat); // 设置新的状态

    void flip(); // 执行翻转动画
    void setStatWithAnimation(int stat); // 设置状态并启动动画

protected:
    void paintEvent(QPaintEvent *event); // 重写绘制事件函数

private:
    int mstat; // 当前状态
    int mframe; // 当前帧数
    QTimer mtimer; // 定时器,用于控制动画帧更新

signals:
};

#endif // COINBUTTON_H // 结束条件编译指令

coinbutton.cpp

#include "coinbutton.h" // 引入自定义 CoinButton 类的头文件
#include <QPainter> // 引入 QPainter 头文件,用于绘图

// 构造函数,初始化 CoinButton 对象
CoinButton::CoinButton(QWidget *parent)
    : QPushButton{parent} // 调用基类 QPushButton 的构造函数
{
    this->setMstat(0); // 设置初始状态为银币
    this->setStyleSheet("QPushButton{border:0px;}"); // 设置按钮样式,去掉边框

    // 连接定时器超时信号到 lambda 函数,用于处理币翻转动画
    connect(&this->mtimer, &QTimer::timeout, [=]() {
        if (this->mstat) // 判断当前状态
            this->mframe--; // 状态为 1 时,银币转金币帧数减少
        else
            this->mframe++; // 状态为 0 时,金币转银币帧数增加

        // 根据当前帧数生成图片路径
        QString frameName = QString(":/image/Coin000%1.png").arg(this->mframe);
        this->setIcon(QIcon(frameName));

        // 如果帧数达到结束帧,即币翻转动画结束,停止定时器
        if (this->mframe == 8 || this->mframe == 1)
        {
            this->mtimer.stop();
        }
    });
}

// 获取当前状态
int CoinButton::getMstat() const
{
    return mstat; // 返回状态
}

// 设置新的状态
void CoinButton::setMstat(int newMstat)
{
    mstat = newMstat; // 更新状态
    // 根据状态设置按钮图标
    if (this->mstat)
        this->setIcon(QIcon(":/image/Coin0001.png")); // 状态为 1 时,显示第 1 帧,为金币
    else
        this->setIcon(QIcon(":/image/Coin0008.png")); // 状态为 0 时,显示第 8 帧,为银币
    this->setIconSize(this->size()); // 设置图标大小为按钮的大小
}

// 执行翻转动画
void CoinButton::flip()
{
    this->setStatWithAnimation(!this->mstat); // 切换状态并启动动画
}

// 设置状态并启动动画
void CoinButton::setStatWithAnimation(int stat)
{
    this->mstat = stat; // 更新状态
    // 根据新的状态设置初始帧数
    if (this->mstat)
        this->mframe = 8; // 状态为 1 时,从第 8 帧开始,银转金
    else
        this->mframe = 1; // 状态为 0 时,从第 1 帧开始,金转银
    this->mtimer.start(30); // 启动定时器,设置帧更新间隔为 30 毫秒
}

// 绘制事件,重写 QPushButton 的 paintEvent
void CoinButton::paintEvent(QPaintEvent *event)
{
    // 绘制背景图片
    QPainter painter(this); // 创建绘图对象
    QPixmap pix(":/image/BoardNode.png"); // 加载背景图片
    // 指定背景图宽度和高度为按钮的宽度和高度
    painter.drawPixmap(0, 0, this->width(), this->height(), pix);
    QPushButton::paintEvent(event); // 调用基类的绘制事件函数
}

dataconfig.h

#ifndef DATACONFIG_H
#define DATACONFIG_H

#include <QObject>
#include <QMap>
#include <QVector>

class dataConfig : public QObject
{
    Q_OBJECT
public:
    explicit dataConfig(QObject *parent = 0);

public:

    QMap<int, QVector< QVector<int> > >mData;



signals:

public slots:
};

#endif // DATACONFIG_H

dataconfig.cpp

#include "dataconfig.h"
#include <QDebug>
dataConfig::dataConfig(QObject *parent) : QObject(parent)
{

     int array1[4][4] = {{1, 1, 1, 1},
                        {1, 1, 0, 1},
                        {1, 0, 0, 0},
                        {1, 1, 0, 1} } ;

     QVector< QVector<int>> v;
     for(int i = 0 ; i < 4;i++)
     {
         QVector<int>v1;
         for(int j = 0 ; j < 4;j++)
         {

            v1.push_back(array1[i][j]);
         }
         v.push_back(v1);
     }

     mData.insert(1,v);


     int array2[4][4] = { {1, 0, 1, 1},
                          {0, 0, 1, 1},
                          {1, 1, 0, 0},
                          {1, 1, 0, 1}} ;

     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array2[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(2,v);



     int array3[4][4] = {  {0, 0, 0, 0},
                           {0, 1, 1, 0},
                           {0, 1, 1, 0},
                           {0, 0, 0, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array3[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(3,v);


     int array4[4][4] = {   {0, 1, 1, 1},
                            {1, 0, 0, 1},
                            {1, 0, 1, 1},
                            {1, 1, 1, 1}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array4[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(4,v);


     int array5[4][4] = {  {1, 0, 0, 1},
                           {0, 0, 0, 0},
                           {0, 0, 0, 0},
                           {1, 0, 0, 1}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array5[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(5,v);


     int array6[4][4] = {   {1, 0, 0, 1},
                            {0, 1, 1, 0},
                            {0, 1, 1, 0},
                            {1, 0, 0, 1}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array6[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(6,v);


     int array7[4][4] = {   {0, 1, 1, 1},
                            {1, 0, 1, 1},
                            {1, 1, 0, 1},
                            {1, 1, 1, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array7[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(7,v);

     int array8[4][4] = {  {0, 1, 0, 1},
                           {1, 0, 0, 0},
                           {0, 0, 0, 1},
                           {1, 0, 1, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array8[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(8,v);

     int array9[4][4] = {   {1, 0, 1, 0},
                            {1, 0, 1, 0},
                            {0, 0, 1, 0},
                            {1, 0, 0, 1}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array9[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(9,v);



     int array10[4][4] = {  {1, 0, 1, 1},
                            {1, 1, 0, 0},
                            {0, 0, 1, 1},
                            {1, 1, 0, 1}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array10[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(10,v);


     int array11[4][4] = {  {0, 1, 1, 0},
                            {1, 0, 0, 1},
                            {1, 0, 0, 1},
                            {0, 1, 1, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array11[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(11,v);

     int array12[4][4] = {  {0, 1, 1, 0},
                            {0, 0, 0, 0},
                            {1, 1, 1, 1},
                            {0, 0, 0, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array12[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(12,v);


     int array13[4][4] = {    {0, 1, 1, 0},
                              {0, 0, 0, 0},
                              {0, 0, 0, 0},
                              {0, 1, 1, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array13[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(13,v);

     int array14[4][4] = {    {1, 0, 1, 1},
                              {0, 1, 0, 1},
                              {1, 0, 1, 0},
                              {1, 1, 0, 1}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array14[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(14,v);


     int array15[4][4] = {   {0, 1, 0, 1},
                             {1, 0, 0, 0},
                             {1, 0, 0, 0},
                             {0, 1, 0, 1}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array15[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(15,v);


     int array16[4][4] = {   {0, 1, 1, 0},
                             {1, 1, 1, 1},
                             {1, 1, 1, 1},
                             {0, 1, 1, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array16[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(16,v);

     int array17[4][4] = {  {0, 1, 1, 1},
                            {0, 1, 0, 0},
                            {0, 0, 1, 0},
                            {1, 1, 1, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array17[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(17,v);


     int array18[4][4] = { {0, 0, 0, 1},
                           {0, 0, 1, 0},
                           {0, 1, 0, 0},
                           {1, 0, 0, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array18[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(18,v);

     int array19[4][4] = {   {0, 1, 0, 0},
                             {0, 1, 1, 0},
                             {0, 0, 1, 1},
                             {0, 0, 0, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array19[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(19,v);

     int array20[4][4] = {  {0, 0, 0, 0},
                            {0, 0, 0, 0},
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}} ;
     v.clear();
     for(int i = 0 ; i < 4;i++)
     {
          QVector<int>v1;
          for(int j = 0 ; j < 4;j++)
          {
             v1.push_back(array20[i][j]);
          }
          v.push_back(v1);
     }

     mData.insert(20,v);


     //测试数据
//    for( QMap<int, QVector< QVector<int> > >::iterator it = mData.begin();it != mData.end();it++ )
//    {
//         for(QVector< QVector<int> >::iterator it2 = (*it).begin(); it2!= (*it).end();it2++)
//         {
//            for(QVector<int>::iterator it3 = (*it2).begin(); it3 != (*it2).end(); it3++ )
//            {
//                qDebug() << *it3 ;
//            }
//         }
//         qDebug() << endl;
//    }


}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2051203.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

音频剪辑用什么工具?试试这三款

音乐&#xff0c;是情感的传递者&#xff0c;是灵魂的慰藉。作为一名音乐人&#xff0c;我一直在探索如何更好地捕捉和表达音乐的精髓。在这个数字化的时代&#xff0c;音频剪辑软件成为了我们表达创意的重要工具。今天&#xff0c;我想从一个音乐人的角度&#xff0c;分享我使…

C语言每日好题(3)

有任何不懂的问题可以评论区留言&#xff0c;能力范围内都会一一回答 #define _CRT_SECURE_NO_WARNING #include <stdio.h> #include <string.h> int main(void) {if ((strlen("abc") - strlen("abcdef")) > 0)printf(">\n")…

CentOS 7 下载/安装

下载 centos安装包下载_开源镜像站-阿里云centos安装包是阿里云官方提供的开源镜像免费下载服务&#xff0c;每天下载量过亿&#xff0c;阿里巴巴开源镜像站为包含centos安装包的几百个操作系统镜像和依赖包镜像进行免费CDN加速&#xff0c;更新频率高、稳定安全。https://mir…

SpringBoot(一)

1.Spring Boot概要 1.1 SpringBoot介绍 随着动态语言的流行&#xff08;Ruby、Scala、Node.js&#xff09;, Java的开发显得格外的笨重&#xff1b;繁多的配置、低下的开发效率、复杂的部署流程以及第三方技术整合难度大。 在上述环境下&#xff0c;Spring Boot由此诞生&#…

每天五分钟计算机视觉:搭建人脸识别的Siamese深度神经网络模型

本文重点 前面的一篇文章中介绍了关于一次学习的问题,解决一次学习问题的关键在于学习到一个函数d,这个d可以计算出两张图片中的人脸是不是同一个人。那么我们需要搭建什么样的神经网络才可以让模型学习出这样的函数d呢?本文我们介绍一下Siamese神经网络结构,它可以帮助我…

快速上手体验MyPerf4J监控springboot应用(docker版快速开始-本地版)

使用MyPerf4J监控springboot应用 快速启动influxdb时序数据库日志收集器telegrafgrafana可视化界面安装最终效果 项目地址 项目简介: 一个针对高并发、低延迟应用设计的高性能 Java 性能监控和统计工具。 价值 快速定位性能瓶颈快速定位故障原因 快速启动 监控本地应用 idea配…

BeagleBone Black 上手

芯片特性 板级功能 资源内存 SDRAM 512MB DDR3L 800MHZ A single 256Mb x16 DDR3L 4Gb (512MB) memory device is used. The memory used is one of two devices: MT41K256M16HA-125 from Micron D2516EC4BXGGB from Kingston It will operate at a clock frequency of 400M…

DDD领域驱动设计的原理与实践

目录 什么是DDD领域驱动设计&#xff1f; 定义与概念&#xff1a; 核心思想&#xff1a; 核心概念&#xff1a; 核心原则&#xff1a; 优势与应用&#xff1a; 与微服务架构和传统三层架构的关系&#xff1a; 理解领域模型 举例 统一语言&#xff08;Ubiquitous Langu…

【C++11】入门基础

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;C从入门至进阶 这里将会不定期更新有关C/C的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目录…

基于Kotlin Multiplatform实现静态文件服务器(三)

Expect 和 Actual expect 关键字用于定义一个多平台通用的声明&#xff0c;即该声明在所有平台上都可用&#xff0c;并且需要在特定平台上实现。actual 关键字通常与 expect 关键字配合使用&#xff0c;用于定义多平台通用的接口和函数&#xff0c;从而允许在不同的平台上使用…

PyTorch--深度学习

onux部署功能 cpu运行时间 3. 自动求导 求导结果为&#xff1a;2 1 1

在java中前后端进行交互使用的内容

前言 本文将讲解在java前后端进行交互时会使用的内容, 过滤器 , 前后端交互时: 同步请求(了解)与异步请求, 后端响应json格式数据, 后端标准响应数据格式 过滤器 首先需要了解什么是过滤器: 过滤器是javaEE中在前向后端发送请求时进行拦截的技术,作用…

Linux系统编程(10)线程资源回收和互斥锁

一、pthread_cancel函数 pthread_cancel 函数用于请求取消一个线程。当调用 pthread_cancel 时&#xff0c;它会向指定的线程发送一个取消请求。 #include <pthread.h>int pthread_cancel(pthread_t thread);thread&#xff1a;要发送取消请求的线程标识符。 成功时&a…

函数递归,匿名、内置行数,模块和包,开发规范

一、递归与二分法 一&#xff09;递归 1、递归调用的定义 递归调用&#xff1a;在调用一个函数的过程中&#xff0c;直接或间接地调用了函数本身 2、递归分为两类&#xff1a;直接与间接 #直接 def func():print(from func)func()func() # 间接 def foo():print(from foo)bar…

mac安装ipd包【金铲铲为例】

mac安装ipd包 安装PlayCover 链接&#xff1a;https://github.com/PlayCover/PlayCover 1、点最新Releases 2、cmd ↓&#xff0c;拉到最下面下载dmg 3、安装 图标拖拽到Applications里 IPA下载 以金铲铲为例&#xff0c;良心砸壳包站点&#xff0c;有能力可以支持一下…

系列:水果甜度个人手持设备检测-行业法律法规

系列:水果甜度个人手持设备检测 --行业法律法规 背景 由于我们目标是制作针对水果的便携或手持式检测仪器&#xff0c;既然是民用产品&#xff0c;必然受一系列法律法规的约束&#xff0c;产品在上市之前将会受各种国家标准和地方标准的检验。本篇章中我们采用启发性搜索的方…

Python自动化:解锁高效工作与生产力的密钥

在当今快节奏的数字时代&#xff0c;自动化已成为提升工作效率、优化流程、减少人为错误的不可或缺的工具。Python&#xff0c;作为一种功能强大、易于学习且应用广泛的编程语言&#xff0c;在自动化领域扮演着举足轻重的角色。无论是数据处理、Web自动化、软件测试&#xff0c…

ETL数据集成丨将SQL Server数据同步至Oracle的具体实现

一、背景 在构建企业级数据架构时&#xff0c;将SQL Server数据库的数据同步至数仓数据库&#xff08;如Oracle&#xff09;是一项至关重要的任务。这一过程不仅促进了跨系统数据的一致性与可用性&#xff0c;还为数据分析、商业智能以及决策支持系统提供了坚实的数据基础。 …

黑神话悟空什么配置可以玩?什么样的游戏本配置可以畅玩《黑神话:悟空》?黑神话悟空电脑配置推荐

相信不少游戏爱好者&#xff0c;近期被《黑神话&#xff1a;悟空》这款游戏刷屏了&#xff0c;预售开启不到5分钟&#xff0c;所有的产品即宣告售罄&#xff0c;预购3天销售额就破亿&#xff0c;并迅速登顶Steam全球榜。作为一款备受期待的国产3A游戏&#xff0c;以其精美的画面…

IOS 10 统一颜色管理和适配深色模式

实现分析 像系统那样&#xff0c;给项目中常用的颜色取名字&#xff0c;这里使用扩展语法实现&#xff0c;好处是可以像访问系统颜色那样访问自定义的颜色。 添加依赖 为了能使用16进制的颜色值&#xff0c;这里通过依赖DynamicColor框架来实现 #颜色工具类 #https://githu…