当前位置: 首页 > news >正文

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

目录

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.5sound->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();  // 显示 SelectScenethis->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); // 创建新的 CoinButtonmCoins[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 头文件,用于继承 QPushButtonclass MyPushButton : public QPushButton // 定义 MyPushButton 类,继承自 QPushButton
{Q_OBJECT // 宏,启用 Qt 的信号与槽机制
public:enum MyPushButtonStat // 定义枚举类型 MyPushButtonStat,用于按钮状态{NORMAL, // 正常状态PRESSED // 按下状态};MyPushButton(QString normalImg, QString pressedImg, QWidget *parent = nullptr); // 构造函数声明,接受正常和按下状态的图片路径,以及父级 widgetvoid 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 时,银币转金币帧数减少elsethis->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 帧,为金币elsethis->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 帧开始,银转金elsethis->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;
//    }}

相关文章:

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

目录 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…...

Linux配置JDK8环境变量

目录 一、yum安装1.1 OpenJDK安装1.2 测试是否能够使用1.3 如何卸载JDK 二、手动安装2.1 下载2.2 上传到linux服务器路径2.3 解压2.4 配置环境变量2.5 测试是否能够使用 一、yum安装 1.1 OpenJDK安装 sudo yum install -y java-1.8.0-openjdk-devel1.2 测试是否能够使用 jav…...

Fiddle抓手机app的包

前言 本次文章讲述的是&#xff0c;fiddle获取手机代理&#xff0c;从而获取手机app的http、https请求&#xff01; 一.下载安装汉化Fiddle 1.点击Fiddler官网下载链接&#xff1a;Download Fiddler Web Debugging Tool for Free by Telerik 2.直接运行&#xff0c;选择自己需…...

Oracle+ASM+High冗余详解及空间计算

Oracle ASM&#xff08;Automatic Storage Management&#xff09;的High冗余模式是一种提供高度数据保护的策略&#xff0c;它通过创建多个数据副本来确保数据的可用性和安全性。 以下是关于Oracle ASM High冗余的详细解释&#xff1a; 一、High冗余的特点 1.数据冗余度 在Hi…...

如何为 Nextcloud 配置自动数据库备份 - 应用程序

自动数据库备份模块简化了生成数据库计划备份的过程。这些备份可以存储在各种位置&#xff0c;包括本地驱动器、FTP 服务器、SFTP 服务器、Dropbox、Google Drive、OneDrive、NextCloud 和 Amazon S3 云存储。用户还可以选择启用自动删除过期备份的功能。此外&#xff0c;用户可…...

child_process.spawn简介

child_process.spawn 是 Node.js 中 child_process 模块的一个重要方法&#xff0c;它用于异步地创建子进程来执行指定的命令。下面是对 child_process.spawn 的深入解析&#xff1a; 一、基本用法 spawn 方法的基本语法如下&#xff1a; const { spawn } require(child_pr…...

整理给测试人看的千页面试题

人往高处走水往低处流&#xff0c;九月已来&#xff0c;“金九银十”招聘季还会远吗&#xff1f; 转眼2024年招聘季就要来了&#xff0c;没点真本事真技术&#xff0c;没点面试经验&#xff0c;不了解点职场套路&#xff0c;如何过五关斩六将&#xff1f;如何打败面试官&#…...

Linux 内核中的并发与竞争

1. 引入并发与竞争的概念 在现代计算环境中&#xff0c;多个任务和线程通常会同时执行&#xff0c;因此理解并发和竞争的特性与挑战至关重要。以下是对这两个概念的详细介绍。 1. 并发&#xff08;Concurrency&#xff09; 定义&#xff1a; 并发是指多个任务在同一时间段内…...

Ubuntu修改命令提示符格式PS1

命令提示符组成 通过Xshell进入Ubuntu的默认提示符是这样的 rootDESKTOP:~# root: 当前登录用户DESKTOP&#xff1a;主机名~: 当前目录名&#xff08;即用户主目录&#xff09;#&#xff1a;超级用户权限(root用户显示)$: 普通用户权限(非root用户显示) 修改命令提示符 step1…...

指针详解(五)

目录 1. 回调函数 2. qsort使用举例 1&#xff09;排序整型数据 2&#xff09;排序结构数据 3. qsort函数的模拟实现&#xff08;冒泡&#xff09; 1. 回调函数 回调函数就是一个通过函数指针调用的函数 函数的指针&#xff08;地址&#xff09;作为参数传递给另一个函数…...

智慧安防/一网统管/视频监控EasyCVR视频汇聚平台的视频轻量化特点及应用

在数字化时代&#xff0c;视频监控已成为保障公共安全、提升管理效率的重要手段。随着技术的不断进步&#xff0c;EasyCVR视频汇聚平台应运而生&#xff0c;平台以其独特的视频轻量化特点在安防监控领域展现出强大的应用潜力。本文将详细探讨EasyCVR视频汇聚平台的视频轻量化特…...

nginx代理转发如何配置

Nginx配置代理转发是一个常见的需求&#xff0c;用于将客户端的请求转发到后端服务器。以下是Nginx代理转发的配置步骤&#xff0c;包括详细的操作步骤和注意事项&#xff1a; 1. 确定Nginx安装和配置文件位置 首先&#xff0c;确保Nginx已经正确安装在服务器上。Nginx的主配…...

JavaScript学习笔记(十三):网络请求JS AJAX

1、AJAX - XMLHttpRequest 对象 1.1 XMLHttpRequest 对象是 AJAX 的基石。 创建 XMLHttpRequest 对象定义回调函数打开 XMLHttpRequest 对象向服务器发送请求 1.2 XMLHttpRequest 对象 所有现代浏览器都支持 XMLHttpRequest 对象。 XMLHttpRequest 对象可用于在后台与 Web…...

go for 循环变量的使用及易错点

1&#xff0c;for 循环变量&#xff0c;整个for循环中变量i始终使用一个变量&#xff0c;i地址不变&#xff0c;存放的内容在变 func main() {for i : 0; i < 10; i {fmt.Printf("值:%v 地址&#xff1a;%v \n", i, &i)} } 打印&#xff1a; 值:0 地址&am…...

2024嵌入式面试:OPPO嵌入式面试题及参考答案

目录 TCP 与 UDP 的区别是什么? 请简述 TCP 的三次握手过程。 HTTP 协议的工作原理是什么? C++11 引入了哪些新特性? 什么是智能指针?如何解决其内存泄漏问题? 进程间有哪些通信方式? CPU 的调度策略有哪些? 如何保证线程安全?多线程编程需要注意哪些问题? S…...

Cesium模型制作,解决Cesium加载glb/GLTF显示太黑不在中心等问题

Cesium模型制作&#xff0c;解决Cesium加载glb/GLTF显示太黑不在中心等问题 QQ可以联系这里&#xff0c;谢谢...

Java 操作 Redis和redis持久化

一、Jedis 我们要使用 Java 来操作 Redis&#xff0c;Jedis 是 Redis 官方推荐的 java连接开发工具&#xff01; 使用Java 操作 Redis 中间件&#xff01; 1.导入对应的依赖 https://mvnrepository.com/artifact/redis.clients/jedis <dependency><groupId>redi…...

Expo创建的React Native项目如何在Windows上进行打包

文章目录 前言eas打包步骤什么是AAB转换为apk文件 本地打包以Windows为例先安装docker&#xff0c;然后手动创建下面的三个文件构建 前言 下面是Expo如何在本地进行打包的过程&#xff08;windows&#xff09; eas打包 如果使用云打包&#xff0c;花费时间较多&#xff0c;时…...

探索Go语言中的结构体:定义和使用

引言 Go语言是一种静态类型的编程语言&#xff0c;它提供了多种数据结构来组织数据。结构体&#xff08;struct&#xff09;是Go中一种强大的自定义数据类型&#xff0c;允许你将多个不同或相同类型的字段组合成一个单一的实体。本文将介绍Go语言中结构体的基本概念、定义方法…...

Unity Dots学习 (一)

先学习怎么使用&#xff0c;再研究底层代码。Dots大家都有所耳闻。一直没时间研究&#xff0c;最近研究一下 看上图可知&#xff0c;哪怕是CPU的第三级缓存也比内存要快2-5倍。 资料&#xff1a; 《DOTS之路》第零节——前导课(1)——DOTS的5W1H问题_哔哩哔哩_bilibili 《DOT…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究

摘要&#xff1a;在消费市场竞争日益激烈的当下&#xff0c;传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序&#xff0c;探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式&#xff0c;分析沉浸式体验的优势与价值…...