目录
QT翻金币小游戏
效果展示
图片
视频
实现代码
main.cpp
mymainwindow.h
mymainwindow.cpp
startscene.h
startscene.cpp
selectscene.cpp
playscene.h
playscene.cpp
dataconfig.h
dataconfig.cpp
QT翻金币小游戏
效果展示
图片
视频
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;
// }
}