视频链接(B站): QT从入门到实战完整版
百度云链接:https://pan.baidu.com/s/1w2knS8G-yXbjCXSTyj7nYw 提取码:07gu
完整项目源码及资源:https://pan.baidu.com/s/1ExEfEakz6v4QHLYDTcIaZQ
提取码:xnob
//配置主场景
//设置固定大小
this->setFixedSize(320,588);
//设置图标
this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
//设置窗口标题
this->setWindowTitle("老帮主带你翻金币");
//退出按钮实现
connect(ui->actionQuit,&QAction::triggered,[=](){
this->close();
});
//注意QAction只能为英文,则退出写作quit,再修改text为中文退出
//mainscene.h
//重写paintEvent事件 画背景图
void paintEvent(QPaintEvent *event);
//mainscene.cpp
#include
//配置主场景
//设置固定大小
this->setFixedSize(320,588);
//设置图标
this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
//设置窗口标题
this->setWindowTitle("翻金币主场景");
//退出按钮实现
connect(ui->actionQuit,&QAction::triggered,[=](){
this->close();
});
void MainScene::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pix;
pix.load(":/res/PlayLevelSceneBg.png");
//绘制背景图
painter.drawPixmap(0,0,this->width(),this->height(),pix);
//画背景上图标
//加载标题
pix.load(":/res/Title.png");
//缩放图片
pix = pix.scaled(pix.width()*0.5,pix.height()*0.5);
//绘制标题
painter.drawPixmap( 10,30,pix.width(),pix.height(),pix);
}
新建C++ class 命名为MyPushButton
//mypushbutton.h
#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H
#include
class MyPushButton : public QPushButton
{
Q_OBJECT
public:
//explicit MyPushButton(QWidget *parent = 0);
//构造函数 参数1 正常显示的图片路径 参数2 按下后显示的图片路径
MyPushButton(QString normalImg,QString pressImg = "");
QString normalImgPath;
QString pressImgPath;
signals:
public slots:
};
#endif // MYPUSHBUTTON_H
//mypushbutton.cpp
#include "mypushbutton.h"
#include
//MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
//{
//}
MyPushButton::MyPushButton(QString normalImg,QString pressImg )
{
this->normalImgPath = normalImg;
this->pressImgPath = pressImg;
QPixmap pix;
bool ret = pix.load(normalImg);
if(!ret)
{
qDebug() << "图片加载失败";
return ;
}
//设置图片固定大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片样式
this->setStyleSheet("QPushButton{border:0px;}");
//设置图标
this->setIcon(pix);
//设置图标大小
this->setIconSize(QSize(pix.width(),pix.height()));
}
//mainscene.cpp
#include "mypushbutton.h"
//在MainScene::MainScene中写入
//开始按钮
MyPushButton * startBtn = new MyPushButton(":/res/MenuSceneStartButton.png");
startBtn->setParent(this);
startBtn->move(this->width() * 0.5 - startBtn->width()*0.5,this->height()*0.7);
//mainscene.cpp
connect(startBtn,&MyPushButton::clicked,[=](){
//qDebug() << "点击了开始";
//做弹起特效
startBtn->zoom1(); //向下跳跃
startBtn->zoom2(); //向上跳跃
});
//mypushbutton.cpp
void MyPushButton::zoom1()
{
//创建动态对象
QPropertyAnimation * animation = new QPropertyAnimation(this,"geometry");
//设置动画时间间隔
animation->setDuration(200);
//起始位置
animation->setStartValue(QRect(this->x(),this->y(),this->width(),this->height()));
animation->setEndValue(QRect(this->x(),this->y()+10,this->width(),this->height()));
//设置弹跳曲线
animation->setEasingCurve(QEasingCurve::OutBounce);
//开始执行动画
animation->start();
}
void MyPushButton::zoom2()
{
//创建动态对象
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->setEasingCurve(QEasingCurve::OutBounce);
//开始执行动画
animation->start();
}
添加新的C++ class文件,类名为ChooseLevelScene 选择基类为QMainWindow
//mainscene.h
#ifndef MAINSCENE_H
#define MAINSCENE_H
#include
#include "chooselevelscene.h"
namespace Ui {
class MainScene;
}
class MainScene : public QMainWindow
{
Q_OBJECT
public:
explicit MainScene(QWidget *parent = 0);
~MainScene();
//重写paintEvent事件 画背景图
void paintEvent(QPaintEvent *event);
//初始化选择关卡场景
ChooseLevelScene * chooseScene = NULL;
private:
Ui::MainScene *ui;
};
#endif // MAINSCENE_H
//mainscene.cpp
#include
//实例化选择关卡场景
chooseScene = new ChooseLevelScene;
connect(startBtn,&MyPushButton::clicked,[=](){
//qDebug() << "点击了开始";
//做弹起特效
startBtn->zoom1(); //向下跳跃
startBtn->zoom2(); //向上跳跃
//延时进入到选择关卡场景中
QTimer::singleShot(500,this,[=](){
//自身隐藏
this->hide();
//显示选择关卡场景
chooseScene->show();
});
});
设置背景图片->创建返回按钮
//chooselevelscene.cpp
#include "chooselevelscene.h"
#include
#include
#include "mypushbutton.h"
#include
ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
//配置选择关卡场景
//设置窗口固定大小
this->setFixedSize(320,588);
//设置图标
this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
//设置标题
this->setWindowTitle("选择关卡");
//创建菜单栏
QMenuBar * bar = this->menuBar();
this->setMenuBar(bar);
//创建开始菜单
QMenu * startMenu = bar->addMenu("开始");
//创建按钮菜单项
QAction * quitAction = startMenu->addAction("退出");
//点击退出 退出游戏
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(),this->height() - backBtn->height());
//点击返回
connect(backBtn,&MyPushButton::clicked,[=](){
qDebug() << "点击了返回按钮";
});
}
void ChooseLevelScene::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pix;
pix.load(":/res/OtherSceneBg.png");
painter.drawPixmap(0,0,this->width(),this->height(),pix);
//加载标题
pix.load(":/res/Title.png");
painter.drawPixmap( (this->width() - pix.width())*0.5,30,pix.width(),pix.height(),pix);
}
//mypushbutton.h
//重写按钮 按下 和释放事件
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
//mypushbutton.cpp
void MyPushButton::mousePressEvent(QMouseEvent *e)
{
if(this->pressImgPath != "") //传入的按下图片不为空,说明需要有按下状态,切换图片
{
QPixmap pix;
bool ret = pix.load(this->pressImgPath);
if(!ret)
{
qDebug() << "图片加载失败";
return ;
}
//设置图片固定大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片样式
this->setStyleSheet("QPushButton{border:0px;}");
//设置图标
this->setIcon(pix);
//设置图标大小
this->setIconSize(QSize(pix.width(),pix.height()));
}
//让父类执行其他内容
return QPushButton::mousePressEvent(e);
}
void MyPushButton::mouseReleaseEvent(QMouseEvent *e)
{
if(this->pressImgPath != "") //传入的按下图片不为空,说明需要有按下状态,切换成初始图片
{
QPixmap pix;
bool ret = pix.load(this->normalImgPath);
if(!ret)
{
qDebug() << "图片加载失败";
return ;
}
//设置图片固定大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片样式
this->setStyleSheet("QPushButton{border:0px;}");
//设置图标
this->setIcon(pix);
//设置图标大小
this->setIconSize(QSize(pix.width(),pix.height()));
}
//让父类执行其他内容
return QPushButton::mouseReleaseEvent(e);
}
//ChooseLevelScene.h
signals:
//写一个自定义信号,告诉主场景 点击了返回
void chooseSceneBack();
//ChooseLevelScene.cpp
//点击返回
connect(backBtn,&MyPushButton::clicked,[=](){
//qDebug() << "点击了返回按钮";
//告诉主场景 我返回了,主场景监听ChooseLevelScene的返回按钮
//延时返回
QTimer::singleShot(500,[=](){
emit this->chooseSceneBack();
});
});
//mainscene.cpp
//监听选择关卡的返回按钮的信号
connect(chooseScene,&ChooseLevelScene::chooseSceneBack,[=](){
chooseScene->hide(); //将选择关卡场景隐藏掉
this->show(); //重新显示主场景
});
//chooselevelscene.cpp
//创建选择关卡的按钮
for(int i = 0 ; i < 20 ; i++)
{
MyPushButton * menuBtn = new MyPushButton(":/res/LevelIcon.png");
menuBtn->setParent(this);
menuBtn->move(25 + (i%4)*70 , 130+ (i/4)*70);
//监听按钮信号
connect(menuBtn,&MyPushButton::clicked,[=](){
QString str = QString("您选择的是第 %1 关").arg(i+1);
qDebug() << str;
});
//按钮上显示的文字
QLabel * label = new QLabel;
label->setParent(this);
label->setFixedSize(menuBtn->width(),menuBtn->height());
label->setText(QString::number(i+1));
label->move(25 + (i%4)*70 , 130+ (i/4)*70);
//设置label上的文字对齐方式 水平居中 和垂直居中
label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
//鼠标事件穿透
label->setAttribute(Qt::WA_TransparentForMouseEvents,true);
}
新建C++ class 文件 命名为 PlayScene
//playscene.h
#ifndef PLAYSCENE_H
#define PLAYSCENE_H
#include
class PlayScene : public QMainWindow
{
Q_OBJECT
public:
//explicit PlayScene(QWidget *parent = 0);
PlayScene(int levelNum);
int levelIndex ; //内部成员属性 记录所选的关卡
signals:
public slots:
};
#endif // PLAYSCENE_H
playscene.cpp
#include "playscene.h"
#include
#include
//PlayScene::PlayScene(QWidget *parent) : QMainWindow(parent)
//{
//}
PlayScene::PlayScene(int levelNum)
{
QString str = QString("进入了第 %1 关").arg(levelNum);
qDebug() << str;
this->levelIndex = levelNum;
//初始化游戏场景
//设置窗口固定大小
this->setFixedSize(320,588);
//设置图标
this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
//设置标题
this->setWindowTitle("翻金币");
//创建菜单栏
QMenuBar * bar = this->menuBar();
this->setMenuBar(bar);
//创建开始菜单
QMenu * startMenu = bar->addMenu("开始");
//创建按钮菜单项
QAction * quitAction = startMenu->addAction("退出");
//点击退出 退出游戏
connect(quitAction,&QAction::triggered,[=](){this->close();});
}
//chooselevelscene.cpp
//ChooseLevelScene构造函数中监听
connect(menuBtn,&MyPushButton::clicked,[=](){
QString str = QString("您选择的是第 %1 关").arg(i+1);
qDebug() << str;
//进入到游戏场景
this->hide(); //将选关场景隐藏掉
play = new PlayScene(i+1); //创建游戏场景
play->show(); //显示游戏场景
});
//playscene.h
//重写paintEvent事件
void paintEvent(QPaintEvent *event);
//playscene.cpp
void PlayScene::paintEvent(QPaintEvent *event)
{
//加载背景
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.width(),pix.height(),pix);
}
//playscene.cpp
//返回按钮
MyPushButton *backBtn = new MyPushButton(":/res/BackButton.png",":/res/BackButtonSelected.png");
backBtn->setParent(this);
backBtn->move(this->width() - backBtn->width(),this->height() - backBtn->height());
//点击返回
connect(backBtn,&MyPushButton::clicked,[=](){
qDebug() << "翻金币场景中,点击了返回按钮";
//告诉主场景 我返回了,选择场景监听ChooseLevelScene的返回按钮
//延时返回
QTimer::singleShot(500,[=](){
emit this->chooseSceneBack();
});
});
//chooselevelscene.cpp
connect(play,&PlayScene::chooseSceneBack,[=](){
this->show();
delete play;
play = NULL;
});
//playscene.cpp
//显示当前关卡数
QLabel * label = new QLabel;
label->setParent(this);
QFont font;
font.setFamily("华文新魏");
font.setPointSize(20);
label->setFont(font);
QString str = QString("Leavel: %1").arg(this->levelIndex);
label->setText(str);
label->setGeometry(QRect(30, this->height() - 50,120, 50)); //设置大小和位置
新建MyCoin的基类为QPushButton
//mycoin.h
#ifndef MYCOIN_H
#define MYCOIN_H
#include
class MyCoin : public QPushButton
{
Q_OBJECT
public:
//explicit MyCoin(QWidget *parent = 0);
//参数 代表 传入的金币路径 还是银币路径
MyCoin(QString btnImg);
signals:
public slots:
};
#endif // MYCOIN_H
//mycoin.h
#include "mycoin.h"
//MyCoin::MyCoin(QWidget *parent) : QPushButton(parent)
//{
//}
MyCoin::MyCoin(QString btnImg)
{
QPixmap pix;
bool ret = pix.load(btnImg);
if(!ret)
{
QString str = QString("图片 %1 加载失败").arg(btnImg);
qDebug() << str;
return;
}
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton{border:0px}");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
}
//playscene.cpp
//创建金币
MyCoin * coin = new MyCoin(":/res/Coin0001.png");
coin->setParent(this);
coin->move(59 + i*50,204+j*50);
//dataconfig.h
#ifndef DATACONFIG_H
#define DATACONFIG_H
#include
#include
#include
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
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 > >::iterator it = mData.begin();it != mData.end();it++ )
// {
// for(QVector< QVector >::iterator it2 = (*it).begin(); it2!= (*it).end();it2++)
// {
// for(QVector::iterator it3 = (*it2).begin(); it3 != (*it2).end(); it3++ )
// {
// qDebug() << *it3 ;
// }
// }
// qDebug() << endl;
// }
}
//mycoin.h
//金币的属性
int posX; //x坐标位置
int posY; //y坐标位置
bool flag; //正反标示
//playscene.cpp
//初始化每个关卡的二维数组
dataConfig config;
for(int i = 0; i < 4 ; i++)
{
for(int j = 0 ; j < 4 ; j++)
{
this->gameArray[i][j] = config.mData[this->levelIndex][i][j];
}
}
//显示金币的背景图片
for(int i = 0 ; i < 4;i++)
{
for(int j = 0 ; j < 4; j++)
{
//绘制背景图片
QLabel* label = new QLabel;
label->setGeometry(0,0,50,50);
label->setPixmap(QPixmap(":/res/BoardNode.png"));
label->setParent(this);
label->move(57 + i*50,200+j*50);
//创建金币
QString str;
if(this->gameArray[i][j] == 1)
{
//显示金币
str = ":/res/Coin0001.png";
}
else
{
str = ":/res/Coin0008.png";
}
MyCoin * coin = new MyCoin(str);
coin->setParent(this);
coin->move(59 + i*50,204+j*50);
//给金币属性赋值
coin->posX = i;
coin->posY = j;
coin->flag = this->gameArray[i][j]; //1正面 0反面
}
}
//mycoin.h
//改变标志的方法
void changeFlag();
QTimer * timer1; //正面翻反面的定时器
QTimer * timer2; //反面翻正面的定时器
int min = 1;
int max = 8;
//mycoin.cpp
MyCoin::MyCoin(QString btnImg)
{
//初始化定时器对象
timer1 = new QTimer(this);
timer2 = new QTimer(this);
//监听正面翻反面的信号 , 并且翻转金币
connect(timer1,&QTimer::timeout,[=](){
QPixmap pix;
QString str = QString(":/res/Coin000%1").arg(this->min++);
pix.load(str);
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton{border:0px}");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
//判断 如果翻完了,将min重置为1
if(this->min > this->max)
{
this->min = 1;
timer1->stop();
}
});
//监听反面翻正面的信号 , 并且翻转金币
connect(timer2,&QTimer::timeout,[=](){
QPixmap pix;
QString str = QString(":/res/Coin000%1").arg(this->max--);
pix.load(str);
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton{border:0px}");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
//判断 如果翻完了,将max重置为8
if(this->min > this->max)
{
this->max = 8;
timer2->stop();
}
});
}
//改变正反面标志的方法
void MyCoin::changeFlag()
{
//如果是正面 翻成反面
if(this->flag)
{
//正面翻反面的定时器
timer1->start(30);
this->flag = false;
}
else //反面翻正面
{
timer2->start(30);
this->flag = true;
}
}
//playscene.cpp
//点击金币 进行翻转
connect(coin,&MyCoin::clicked,[=](){
coin->changeFlag();
this->gameArray[i][j] = this->gameArray[i][j] == 0 ? 1 : 0;
});
在MyCoin中加入了 isAnimation 判断 是否正在做动画条件
当按下 MyCoin 判断是否在做动画,如果做动画,直接return,保证金币和银币动态切换的完整效果
//mycoin.h
//执行动画 标志
bool isAnimation = false;
//重写 按下
void mousePressEvent(QMouseEvent *e);
//mycoin.cpp
#include "mycoin.h"
//MyCoin::MyCoin(QWidget *parent) : QPushButton(parent)
//{
//}
MyCoin::MyCoin(QString btnImg)
{
QPixmap pix;
bool ret = pix.load(btnImg);
if(!ret)
{
QString str = QString("图片 %1 加载失败").arg(btnImg);
qDebug() << str;
return;
}
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton{border:0px}");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
//初始化定时器对象
timer1 = new QTimer(this);
timer2 = new QTimer(this);
//监听正面翻反面的信号 , 并且翻转金币
connect(timer1,&QTimer::timeout,[=](){
QPixmap pix;
QString str = QString(":/res/Coin000%1").arg(this->min++);
pix.load(str);
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton{border:0px}");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
//判断 如果翻完了,将min重置为1
if(this->min > this->max)
{
this->min = 1;
isAnimation = false; //停止做动画了
timer1->stop();
}
});
//监听反面翻正面的信号 , 并且翻转金币
connect(timer2,&QTimer::timeout,[=](){
QPixmap pix;
QString str = QString(":/res/Coin000%1").arg(this->max--);
pix.load(str);
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton{border:0px}");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
//判断 如果翻完了,将max重置为8
if(this->min > this->max)
{
this->max = 8;
isAnimation = false; //停止做动画了
timer2->stop();
}
});
}
void MyCoin::mousePressEvent(QMouseEvent *e)
{
if(this->isAnimation)
{
return;
}
else
{
QPushButton::mousePressEvent(e);
}
}
//改变正反面标志的方法
void MyCoin::changeFlag()
{
//如果是正面 翻成反面
if(this->flag)
{
//正面翻反面的定时器
timer1->start(30);
isAnimation = true; //开始做动画了
this->flag = false;
}
else //反面翻正面
{
timer2->start(30);
isAnimation = true; //开始做动画了
this->flag = true;
}
}
//playscene.cpp
//翻转周围硬币
//周围的右侧金币翻转的条件,延时翻转
QTimer::singleShot(300,this,[=](){
if(coin->posX + 1 <= 3 )
{
coinBtn[coin->posX+1][coin->posY]->changeFlag();
this->gameArray[coin->posX+1][coin->posY] = this->gameArray[coin->posX+1][coin->posY] == 0 ? 1 : 0;
}
//周围的左侧硬币翻转条件
if(coin->posX - 1 >= 0)
{
coinBtn[coin->posX-1][coin->posY]->changeFlag();
this->gameArray[coin->posX-1][coin->posY] = this->gameArray[coin->posX-1][coin->posY] == 0 ? 1 : 0;
}
//周围的下侧硬币翻转条件
if(coin->posY + 1 <= 3)
{
coinBtn[coin->posX][coin->posY + 1]->changeFlag();
this->gameArray[coin->posX][coin->posY + 1] = this->gameArray[coin->posX][coin->posY+1] == 0 ? 1 : 0;
}
//周围的上侧硬币翻转条件
if(coin->posY - 1 >= 0)
{
coinBtn[coin->posX][coin->posY - 1]->changeFlag();
this->gameArray[coin->posX][coin->posY - 1] = this->gameArray[coin->posX][coin->posY-1] == 0 ? 1 : 0;
}
});
//mycoin.h
bool isWin = false; //是否胜利
//playscene.h
bool isWin; //是否胜利
//mycoin.cpp
void MyCoin::mousePressEvent(QMouseEvent *e)
{
if(this->isAnimation || this->isWin)
{
qDebug() << "无法点击";
return;
}
else
{
QPushButton::mousePressEvent(e);
}
}
//playscene.cpp
//判断是否胜利
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() << "游戏胜利";
//将所有按钮的胜利标志改为true
//如果再次点击按钮,直接return,不做响应
for(int i = 0 ; i < 4 ; i++)
{
for(int j = 0 ; j < 4 ; j++)
{
coinBtn[i][j]->isWin = true;
}
}
}
//playscene.cpp
//胜利图片
QLabel* winLabel = new QLabel;
QPixmap tmpPix;
tmpPix.load(":/res/LevelCompletedDialogBg.png");
winLabel->setGeometry(0,0,tmpPix.width(),tmpPix.height());
winLabel->setPixmap(tmpPix);
winLabel->setParent(this);
winLabel->move( (this->width() - tmpPix.width())*0.5 , -tmpPix.height());
//将胜利的图片移动下来
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();
//执行动画 标志
bool isAnimation = false;
bool isWin = false; //是否胜利
//点击按钮 将所有按钮先都禁用
for(int i = 0 ; i < 4 ; i++)
{
for(int j = 0 ; j < 4 ; j++)
{
this->coinBtn[i][j]->isWin = true;
}
}
//翻完周围金币后,将所有金币解开禁用
for(int i = 0 ; i < 4 ; i++)
{
for(int j = 0 ; j < 4 ; j++)
{
this->coinBtn[i][j]->isWin = false;
}c
}
//mainscene.cpp
//QT += multimedia
#include //多媒体模块下的 音效头文件
//准备开始按钮的音效
QSound * startSound = new QSound(":/res/TapButtonSound.wav",this);
//循环播放 -1表示无限循环
//startSound->setLoops(10);
//startSound->play();
connect(startBtn,&MyPushButton::clicked,[=](){
//qDebug() << "点击了开始";
//播放开始音效资源
startSound->play();
});
//playscene.cpp
//添加音效资源
//翻金币音效
QSound *flipSound = new QSound(":/res/ConFlipSound.wav",this);
//胜利按钮音效
QSound *winSound = new QSound(":/res/LevelWinSound.wav",this);
//返回按钮音效
QSound *backSound = new QSound(":/res/BackButtonSound.wav",this);
选择release编译
找到对应的exe程序中打开cmd 输入命令 windeployqt CoinFlip.exe打包项目
NIS Edit第三方进一步进行压缩