项目介绍
界面演示
规则说明
翻金币是一个简单的游戏,在翻金币场景中点击界面中的币可以进行翻转,翻转规则是币加其上下左右的币同时进行翻转(动画做了一些小延迟),胜利的条件是界面中全是金币。
实现步骤分解
由界面演示,我们知道这个界面主要就3个界面:
- 翻金币的主界面
- 选择关卡界面
- 翻金币场景界面
界面详述
翻金币的主界面
说明
翻金币主界面有一个菜单栏,菜单栏有一个开始菜单,开始菜单里面只有一项退出,点击退出,游戏结束。
主界面还有一个START
按钮,点击START
按钮,可以跳到翻金币的选择关卡界面。
其余则是背景和标题栏还有一个Label
实现步骤
创建一个MainScence类,因为需要一个菜单栏,所以选择继承QMainWindow
mainScence.h
#ifndef MAINSCENCE_H
#define MAINSCENCE_H
#include <QMainWindow>
#include"mypushbutton.h"
#include"chooeslevelscreen.h"
namespace Ui {
class MainScence;
}
class MainScence : public QMainWindow
{
Q_OBJECT
public:
explicit MainScence(QWidget *parent = 0);
~MainScence();
void paintEvent(QPaintEvent *);
ChooesLevelscreen *chooseScence;
private:
Ui::MainScence *ui;
};
#endif // MAINSCENCE_H
在.h文件中重写了一个paintEvent()函数,这个函数会被主动调用,无需手动调用,创建一个ChooesLevelscreen对象,这个对象用来关联跳转。
mainScence.cpp
#include "mainscence.h"
#include "ui_mainscence.h"
#include<QPainter>
#include<QTimer>
#include<QSound>
MainScence::MainScence(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainScence)
{
ui->setupUi(this);
// 点击开始 - 退出游戏
connect(ui->actionQuit,&QAction::triggered,[=](){
this->close();
});
//设置固定大小
this->setFixedSize(320,588);
//设置标题
this->setWindowTitle("翻金币");
//设置图片
this->setWindowIcon(QIcon(":/res/Coin0001.png"));
//开始按钮的创建
MyPushButton *startBtn = new MyPushButton(":/res/MenuSceneStartButton.png");
startBtn->setParent(this);
startBtn->move(this->width()*0.5-startBtn->width()*0.5,this->height()*0.7);
//准备开始按钮音效
QSound *startSound = new QSound(":/res/TapButtonSound.wav",this);
//设置循环次数
startSound->setLoops(-1);//如果是-1代表无限循环
//创建出第二个界面 - 选择关卡
chooseScence = new ChooesLevelscreen;
//监听第二个选择关卡场景中的返回按钮的信号
connect(chooseScence,&ChooesLevelscreen::chooseScenceBack,[=](){
chooseScence->hide();
//将自身的位置同步为选择关卡场景的位置
this->setGeometry(chooseScence->geometry());
this->show();
});
connect(startBtn,&MyPushButton::clicked,[=](){
//qDebug()<<"点击了开始按钮";
//播放开始的音效
startSound->play();
//设置开始按钮的点击效果
startBtn->Jump1();
startBtn->Jump2();
//延时 进入到第二个界面
QTimer::singleShot(500,this,[=](){
//将自身隐藏调用
this->hide();
//进入到第二个界面 - 选择关卡
chooseScence->setGeometry(this->geometry());
chooseScence->show();
});
});
}
void MainScence::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);
painter.drawPixmap(10,30,pix);
}
MainScence::~MainScence()
{
delete ui;
}
选择关卡界面
说明
选择关卡界面也是有一个·菜单栏,其效果和实现和主界面一致,中心是一个选择关卡的功能,目前是20个关卡。
还有一个BACK
按钮,用来触发返回上一界面的功能
具体实现
chooesLevelscreen.h
#ifndef CHOOESLEVELSCREEN_H
#define CHOOESLEVELSCREEN_H
#include <QMainWindow>
#include"playscene.h"
class ChooesLevelscreen : public QMainWindow
{
Q_OBJECT
public:
explicit ChooesLevelscreen(QWidget *parent = nullptr);
void paintEvent(QPaintEvent *);
//维护游戏场景的指针
PlayScene *playScene;
signals:
//自定义的信号,只需要声明,不需要实现
void chooseScenceBack();
public slots:
};
#endif // CHOOESLEVELSCREEN_H
chooesLevelscreen.cpp
#include "chooeslevelscreen.h"
#include<QMenuBar>
#include<QMenu>
#include<QAction>
#include<QPainter>
#include<QTimer>
#include<QLabel>
#include<QSound>
#include"mypushbutton.h"
ChooesLevelscreen::ChooesLevelscreen(QWidget *parent) : QMainWindow(parent)
{
//设置固定大小
this->setFixedSize(320,588);
//设置标题
this->setWindowTitle("选择关卡");
//设置图片
this->setWindowIcon(QIcon(":/res/Coin0001.png"));
//创建菜单栏
QMenuBar *bar =menuBar();
this->setMenuBar(bar);
//创建菜单
QMenu *startMenu = bar->addMenu("开始");
//创建菜单项
QAction *quitAction = startMenu->addAction("退出");
//创建选择关卡的音效
QSound *chooesSound = new QSound(":/res/TapButtonSound.wav",this);
//返回按钮音效
QSound *backSound = new QSound(":/res/BackButtonSound.wav",this);
//点击退出按钮 实现退出游戏
connect(quitAction,&QAction::triggered,[=](){
this->close();
});
//返回按钮的创建
MyPushButton *backBtn = new MyPushButton(":/res/BackButton.png",":/res/BackButtonSelected.png");
backBtn->setParent(this);
backBtn->move(this->width()-backBtn->width()-5,this->height()-backBtn->height()-10);
connect(backBtn,&MyPushButton::clicked,[=](){
backSound->play();
//
QTimer::singleShot(300,this,[=](){
emit this->chooseScenceBack();
});
});
playScene = NULL;
//选择关卡按钮
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;
//点击选择的关卡触发音效
chooesSound->play();
//隐藏掉自身
this->hide();
playScene = new PlayScene(i+1);
playScene->setGeometry(this->geometry());
playScene->show();
connect(playScene,&PlayScene::chooseScenceBack,[=](){
//选择关卡的场景
playScene->hide();
this->setGeometry(playScene->geometry());
QTimer::singleShot(300,this,[=](){
delete playScene;
playScene = NULL;
this->show();
});
});
});
QLabel *label = new QLabel(this);
//设置大小
label->setFixedSize(menuBtn->width(),menuBtn->height());
//设置文本内容
label->setText(QString::number(i+1));
//设置位置
label->move(25+(i%4)*70,130+(i/4)*70);
//设置居中效果
label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
//设置鼠标穿透
label->setAttribute(Qt::WA_TransparentForMouseEvents);//51 鼠标穿透
}
}
void ChooesLevelscreen::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(),pix.height());
painter.drawPixmap(10,30,pix);
}
翻金币场景
说明
关卡的内容与数组连接,目前的是44的二维数组,而关卡的具体选择则靠选择界面传入的index值,这个值还用来判断关卡,
关于数组数据
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);
QMap<int,QVector<QVector<int>> > mData;
signals:
public slots:
};
#endif // DATACONFIG_H
dataConfig.cpp
这里偷懒了,还没改具体数据,可以自行更改0或1,或者其他数据,不过除1以外的数据走的都是0的实现
#include "dataconfig.h"
DataConfig::DataConfig(QObject *parent) : QObject(parent)
{
//1
int arrary1[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(arrary1[i][j]);
}
v.push_back(v1);
}
mData.insert(1,v);
//2
int arrary2[4][4] ={{1,1,1,1},
{1,0,0,1},
{1,0,1,0},
{1,0,0,1}};
QVector<QVector<int>> v2;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary2[i][j]);
}
v2.push_back(v1);
}
mData.insert(2,v2);
//3
int arrary3[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v3;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary3[i][j]);
}
v3.push_back(v1);
}
mData.insert(3,v3);
//4
int arrary4[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v4;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary4[i][j]);
}
v4.push_back(v1);
}
mData.insert(4,v4);
//5
int arrary5[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v5;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary5[i][j]);
}
v5.push_back(v1);
}
mData.insert(5,v5);
//6
int arrary6[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v6;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary6[i][j]);
}
v6.push_back(v1);
}
mData.insert(6,v6);
//7
int arrary7[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v7;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary7[i][j]);
}
v7.push_back(v1);
}
mData.insert(7,v7);
//8
int arrary8[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v8;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary8[i][j]);
}
v8.push_back(v1);
}
mData.insert(8,v8);
//9
int arrary9[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v9;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary9[i][j]);
}
v9.push_back(v1);
}
mData.insert(9,v9);
//10
int arrary10[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v10;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary10[i][j]);
}
v10.push_back(v1);
}
mData.insert(10,v10);
//11
int arrary11[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v11;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary11[i][j]);
}
v11.push_back(v1);
}
mData.insert(11,v11);
//12
int arrary12[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v12;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary12[i][j]);
}
v12.push_back(v1);
}
mData.insert(12,v12);
//13
int arrary13[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v13;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary13[i][j]);
}
v13.push_back(v1);
}
mData.insert(13,v13);
//14
int arrary14[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v14;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary14[i][j]);
}
v14.push_back(v1);
}
mData.insert(14,v14);
//15
int arrary15[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v15;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary15[i][j]);
}
v15.push_back(v1);
}
mData.insert(15,v15);
//16
int arrary16[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v16;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary16[i][j]);
}
v16.push_back(v1);
}
mData.insert(16,v16);
//17
int arrary17[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v17;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary17[i][j]);
}
v17.push_back(v1);
}
mData.insert(17,v17);
//18
int arrary18[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v18;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary18[i][j]);
}
v18.push_back(v1);
}
mData.insert(18,v18);
//19
int arrary19[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v19;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary19[i][j]);
}
v19.push_back(v1);
}
mData.insert(19,v19);
//20
int arrary20[4][4] ={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v20;
for(int i=0;i<4;i++){
QVector<int> v1;
for(int j=0;j<4;j++){
v1.push_back(arrary20[i][j]);
}
v20.push_back(v1);
}
mData.insert(20,v20);
}
回到翻金币关卡的具体实现
playScene.h
#ifndef PLAYSCENE_H
#define PLAYSCENE_H
#include <QMainWindow>
#include<QDebug>
#include<QMenu>
#include<QAction>
#include<QMenuBar>
#include<QPainter>
#include"mypushbutton.h"
#include<QTimer>
#include"mycoin.h"
class PlayScene : public QMainWindow
{
Q_OBJECT
public:
//explicit PlayScene(QWidget *parent = nullptr);
PlayScene(int index);
//记录当前本关的关卡号
int leaveIndex;
void paintEvent(QPaintEvent *);
//游戏二维数组 维护里面金币或银币优势
int gameArray[4][4];
//存放金币的二维数组
MyCoin *coinBtn[4][4];
//是否胜利的标志
bool isWin;
signals:
void chooseScenceBack();
public slots:
};
#endif // PLAYSCENE_H
playScene.cpp
#include "playscene.h"
#include<QLabel>
#include"mycoin.h"
#include"dataconfig.h"
#include<QPropertyAnimation>
#include<QSound>
PlayScene::PlayScene(int index)
{
// QString str = QString("现在是第 %1 关").arg(index);
// qDebug()<<str;
this->leaveIndex = index;
//设置固定大小
this->setFixedSize(320,588);
//设置标题
this->setWindowTitle("翻金币场景");
//设置图片
this->setWindowIcon(QIcon(":/res/Coin0001.png"));
//创建菜单栏
QMenuBar *bar =menuBar();
this->setMenuBar(bar);
//创建菜单
QMenu *startMenu = bar->addMenu("开始");
//创建菜单项
QAction *quitAction = startMenu->addAction("退出");
//点击退出按钮 实现退出游戏
connect(quitAction,&QAction::triggered,[=](){
this->close();
});
//默认未胜利
isWin = false;
//显示具体关卡号
QLabel *label = new QLabel;
label->setParent(this);
QString str = QString("level:%1").arg(this->leaveIndex);
QFont font;
font.setFamily("华文新魏");
font.setPointSize(20);
font.setBold(true);
font.setItalic(true);
//让创建的label使用上面的字体
label->setFont(font);
label->setText(str);
//设置位置
label->setGeometry(QRect(30,this->height()-60,150,60));
//返回按钮音效
QSound *backSound = new QSound(":/res/BackButtonSound.wav",this);
//金币翻转音效
QSound *flipSound = new QSound(":/res/ConFlipSound.wav",this);
//游戏胜利音效
QSound *winSound = new QSound(":/res/LevelWinSound.wav",this);
//返回按钮的创建
MyPushButton *backBtn = new MyPushButton(":/res/BackButton.png",":/res/BackButtonSelected.png");
backBtn->setParent(this);
backBtn->move(this->width()-backBtn->width()-5,this->height()-backBtn->height()-10);
connect(backBtn,&MyPushButton::clicked,[=](){
//
backSound->play();
QTimer::singleShot(300,this,[=](){
emit this->chooseScenceBack();
});
});
DataConfig data;
//初始化游戏中的二维数组
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
this->gameArray[i][j] = data.mData[this->leaveIndex][i][j];
}
}
//创建胜利的图片
QLabel *winLabel = new QLabel;
QPixmap pix;
pix.load(":/res/LevelCompletedDialogBg.png");
winLabel->setGeometry(QRect(0,0,pix.width(),pix.height()));
winLabel->setParent(this);
winLabel->setPixmap(pix);
winLabel->move((this->width()-pix.width())*0.5,-pix.height());
//创建金币的背景图片
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
QLabel *bg =new QLabel(this);
QPixmap pix;
pix.load(":/res/BoardNode.png");
bg->setGeometry(0,0,pix.width(),pix.height());
bg->setPixmap(pix);
bg->move(57+i*50,200+j*50);
//创建金币
QString str;
if(this->gameArray[i][j] ==1){
//为1就是金币
str=":/res/Coin0001.png";
}else{
//其他情况是银币
str=":/res/Coin0008.png";
}
MyCoin *coin = new MyCoin(str);
coin->setParent(this);
coin->posX =i;
coin->posY = j;
coin->flag = this->gameArray[i][j];
coin->move(59+i*50,204+j*50);
//将coin放入到维护的金币的二维数组
coinBtn[i][j] = coin;
connect(coin,&MyCoin::clicked,[=](){
//翻动金币音效
flipSound->play();
//在翻动金币时,禁用其他金币的点击事件
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
this->coinBtn[i][j]->isWin = true;
}}
coin->chageFlag();
gameArray[i][j] = gameArray[i][j] == 0?1:0;
//继续翻动周围的硬币
//延时翻周围的金币
QTimer::singleShot(200,this,[=](){
//检测翻右侧金币
if(coin->posX+1<=3){
coinBtn[coin->posX+1][coin->posY]->chageFlag();
gameArray[coin->posX+1][coin->posY] = gameArray[coin->posX+1][coin->posY] == 0 ? 1 : 0;
}
//检测翻左侧金币
if(coin->posX-1>=0){
coinBtn[coin->posX-1][coin->posY]->chageFlag();
gameArray[coin->posX-1][coin->posY] = gameArray[coin->posX-1][coin->posY] == 0 ? 1 : 0;
}
//检测翻上侧金币
if(coin->posY-1>=0){
coinBtn[coin->posX][coin->posY-1]->chageFlag();
gameArray[coin->posX][coin->posY-1] = gameArray[coin->posX][coin->posY-1] ==0?1:0;
}
//检测翻下侧金币
if(coin->posY+1<=3){
coinBtn[coin->posX][coin->posY+1]->chageFlag();
gameArray[coin->posX][coin->posY+1] = gameArray[coin->posX][coin->posY+1] ==0?1:0;
}
//在翻完金币后,打开其他金币的点击效果
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
this->coinBtn[i][j]->isWin = false;
}}
//在翻完周围金币后检测游戏是否胜利
this->isWin = true;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(coinBtn[i][j]->flag == false){
this->isWin = false;
break;
}
}
}
if(this->isWin==true){
// qDebug()<<"游戏胜利";
winSound->play();
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
coinBtn[i][j]->isWin = true;
}
}
//将胜利的标志显示出来
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()+114,winLabel->width(),winLabel->height()));
animation->setEasingCurve(QEasingCurve::OutBounce);
animation->start();
}
});
});
}
}
}
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);
painter.drawPixmap(10,30,pix);
}
界面之外还有两个自定义控件
金币类
myCoin.h
#ifndef MYCOIN_H
#define MYCOIN_H
#include<QString>
#include<QPushButton>
#include<QTimer>
class MyCoin : public QPushButton
{
Q_OBJECT
public:
//explicit MyCoin(QWidget *parent = nullptr);
MyCoin(QString coinImg);
//位置与正反标志
int posX;
int posY;
bool flag;
//改变标志 计时器 和图片拼接尾
void chageFlag();
QTimer *timer1;
QTimer *timer2;
int min =1;
int max = 8;
//是否在执行动画的标识
bool isAnimation;
bool isWin;//是否胜利的标志
void mousePressEvent(QMouseEvent *e);
signals:
public slots:
};
#endif // MYCOIN_H
myCoin.cpp
#include "mycoin.h"
#include<QMessageBox>
#include<QPixmap>
#include<QString>
MyCoin::MyCoin(QString coinImg)
{
QPixmap pix;
bool ret = pix.load(coinImg);
if(!ret){
QString str = QString("图片加载失败 %1").arg(coinImg);
QMessageBox::critical(this,"加载失败",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);
isAnimation = false;
isWin = false;
//监听定时器
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()));
//如果显示到了最后一张,停止定时器
if(this->min>this->max){
this->min =1;
timer1->stop();
isAnimation = false;
}
});
//监听定时器
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()));
//如果显示到了最后一张,停止定时器
if(this->max < this->min){
this->max =8;
timer2->stop();
isAnimation = false;//动画结束后,还原动画标志
}
});
}
//改变标志,执行翻转效果
void MyCoin::chageFlag(){
isAnimation = true;
if(this->flag){
//开启正面 翻 反面 的定时器
timer1->start(30);
this->flag = false;
}
else{
timer2->start(30);
this->flag = true;
}
}
void MyCoin::mousePressEvent(QMouseEvent *e){
if(this->isAnimation|| this->isWin){
//如果正在做动画,直接返回
return;
}
else{
//如果是其他情况,则直接交给父类去处理
QPushButton::mousePressEvent(e);
}
}
自定义按钮类
mypushbutton.h
#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H
#include <QPushButton>
#include<QDebug>
#include<QPropertyAnimation>
class MyPushButton : public QPushButton
{
Q_OBJECT
public:
//explicit MyPushButton(QWidget *parent = nullptr);
MyPushButton(QString normalImg,QString pressImg="");
QString normalImg;
QString pressImg;
//向下跳跃
void Jump1();
//向上跳跃
void Jump2();
//鼠标按下
void mousePressEvent(QMouseEvent *e);
//鼠标释放
void mouseReleaseEvent(QMouseEvent *e);
signals:
public slots:
};
#endif // MYPUSHBUTTON_H
mypushbutton.cpp
#include "mypushbutton.h"
MyPushButton::MyPushButton(QString normalImg,QString pressImg){
this->normalImg = normalImg;
this->pressImg = pressImg;
QPixmap pix;
bool ret = pix.load(this->normalImg);
if(!ret){
QString str = QString("%1 图片加载失败").arg(this->normalImg);
qDebug()<<str;
return;
}
//设置图片大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片的样式
this->setStyleSheet("QPushButton{border:0px;}");
//设置图片
this->setIcon(pix);
//设置图片大小
this->setIconSize(QSize(pix.width(),pix.height()));
}
//向下跳跃
void MyPushButton::Jump1(){
QPropertyAnimation *animation =new QPropertyAnimation(this,"geometry");
//设置时间间隔
animation->setDuration(200);
//设置动画对象的起始位置
animation->setStartValue(QRect(this->x(),this->y()+10,this->width(),this->height()));
//设置动画对象的终止位置
animation->setEndValue(QRect(this->x(),this->y(),this->width(),this->height()));
//执行动画
animation->start();
}
//向上跳跃
void MyPushButton::Jump2(){
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->start();
}
//鼠标按下的事件
void MyPushButton::mousePressEvent(QMouseEvent *e){
if(this->pressImg != ""){
QPixmap pix;
bool ret = pix.load(this->pressImg);
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()));
}
//其他的事件,父类会处理
QPushButton::mousePressEvent(e);
}
//鼠标释放的事件
void MyPushButton::mouseReleaseEvent(QMouseEvent *e){
if(this->pressImg != ""){
QPixmap pix;
bool ret = pix.load(this->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()));
}
QPushButton::mouseReleaseEvent(e);
}
其他说明
在使用QSound
,还需要在.pro文件中添加multimedia
QT += core gui multimedia
关于资源文件,可以直接从我记录的代码中抄,以下是阿里云链接,如果因未知原因失效,可以私信我
https://www.aliyundrive.com/s/nudt3aTvVrH
引用说明
以上是传智教育的QT界面开发的翻金币案例学习笔记