- 在学习QT的过程中,发现翻金币是一个很好的案例,故而学习,代码会有略微不同,是学习笔记。
目录
4.关卡选择界面:choose_page.h/choose_page.cpp
5.准备游戏数据:game_data.h/game_data.cpp
7.游戏界面:play_page.h/paly_page.cpp
![](https://img-blog.csdnimg.cn/289bbe70837e4db8a6986aa303226415.png)
![](https://img-blog.csdnimg.cn/4b39fe541e8e4f94834d3e76f3e0d439.png)
![](https://img-blog.csdnimg.cn/5ad8728c3f684186aae7689d93d6a064.png)
1.主函数main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
2.自定义按钮:mypushbutton.h/mypushbutton.cpp
-
mypushbutton.h
#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H
#include <QWidget>
#include <QPushButton>
#include <QString>
#include <choose_page.h>
class Mypushbutton : public QPushButton
{
Q_OBJECT
public:
//explicit Mypushbutton(QWidget *parent = nullptr);
Mypushbutton(QString normalImg,QString pressImg="");//重载有参构造函数
//默认显示图片路径
QString normalImgPath;
//按下后显示图片路径
QString pressImgpath;
void zoomdown();//向下跳跃
void zoomup();//向上跳跃
void mousePressEvent(QMouseEvent *e);//重载鼠标按下事件
void mouseReleaseEvent(QMouseEvent *e);//重载鼠标松开事件
signals:
public slots:
};
#endif // MYPUSHBUTTON_H
-
mypushbutton.cpp
#include "mypushbutton.h"
#include <QPropertyAnimation>//动画
#include <QPixmap>
#include <QDebug>
#include <QMouseEvent>
#include <QString>
//自定义按钮,更改构造参数(正常显示的图片路径,按下后显示的图片路径)
Mypushbutton::Mypushbutton(QString normalImg,QString pressImg)
{
this->normalImgPath=normalImg;
this->pressImgpath=pressImg;
//加载图片,以及判断图片存在
QPixmap pix;
bool ret=pix.load(normalImgPath);
if(!ret)
qDebug() << "图片加载失败";
//设置图片的固定大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片的样式表(暂不需要)
//设置图片(?)
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
}
//QVariant,能够存放多个不同类型的值
void Mypushbutton::zoomdown(){//向下跳跃
QPropertyAnimation *animation =new QPropertyAnimation(this,"geometry");//geometry几何?,创建动画对象
animation->setDuration(200);//播放时长
animation->setStartValue(QVariant(QRect(this->x(),this->y(),this->width(),this->height())));//设置开始位置和大小
animation->setEndValue(QVariant(QRect(this->x(),this->y(),this->width(),this->height())));
animation->setEasingCurve(QEasingCurve::OutBounce);//设置动画的节奏
animation->start();
}
void Mypushbutton::zoomup(){//向上跳跃
QPropertyAnimation *animation =new QPropertyAnimation(this,"geometry");//geometry几何?,创建动画对象
animation->setDuration(200);//播放时长
animation->setStartValue(QVariant(QRect(this->x(),this->y()+10,this->width(),this->height())));//设置开始位置和大小
animation->setEndValue(QVariant(QRect(this->x(),this->y(),this->width(),this->height())));
animation->setEasingCurve(QEasingCurve::OutBounce);//设置动画的节奏
animation->start();
}
//Qsize,一个矩形区域大小
void Mypushbutton::mousePressEvent(QMouseEvent *e){//重载鼠标按下事件
//判断图片存在
if(pressImgpath!=""){
QPixmap pix;
bool ret=pix.load(pressImgpath);
if(!ret)
qDebug() << pressImgpath << "加载图片失败";
this->setFixedSize(pix.width(),pix.height());
//this->setStyleSheet();
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));//
}
return QPushButton::mousePressEvent(e);
}
void Mypushbutton::mouseReleaseEvent(QMouseEvent *e){//重载鼠标松开事件
//判断图片存在
if(pressImgpath!=""){
QPixmap pix;
bool ret=pix.load(pressImgpath);
if(!ret)
qDebug() << pressImgpath << "加载图片失败";
this->setFixedSize(pix.width(),pix.height());
//this->setStyleSheet();
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
}
return QPushButton::mousePressEvent(e);
}
3.开始界面:widget.h/widget.cpp
-
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <choose_page.h>
#include <mypushbutton.h>
#include <play_page.h>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
//重写painEvent事件画背景图
void paintEvent(QPaintEvent *);
~Widget();
public slots:
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
-
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QTimer>
#include <QIcon>
#include <choose_page.h>
#include <QPainter>
#include <QPixmap>
#include <QLabel>
#include <QMovie>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//设置窗体
this->setFixedSize(350,600); //大小
this->setWindowTitle("大战罗小黑"); //标题栏
this->setStyleSheet("QPushButton{border:0px}"); //样式表,无边框
this->setWindowIcon(QIcon(":/img/lxh.png")); //左上角图标
//菜单没写
//注册选择关卡页面
choose_page *choose_pg=new choose_page;
//创建开始按钮
Mypushbutton *startbtn=new Mypushbutton(":/img/lxh.png",":/img/bt5.png");
startbtn->setParent(this);
startbtn->move(this->width()*0.5-startbtn->width()*0.5,this->height()*0.47);//这是以整个界面大小为准找位置
//监听开始按钮点击事件,执行动画,写lambda表达式
/*[] 不捕获任何变量。
* [&] 捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获)。
* [=] 捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获)。
* */
connect(startbtn,&Mypushbutton::pressed,[=](){//为什么我的clicked不行,而pressed可以
startbtn->zoomdown();
//startbtn->zoomup();
//延时100ms进入关卡选择
QTimer::singleShot(100,this,[&](){
this->hide(); //该界面隐藏
choose_pg->setGeometry(this->geometry()); //界面继承
choose_pg->show();//显示关卡选择界面
});
});
//监听选择场景返回按钮的自定义信号
connect(choose_pg,&choose_page::chooseSceneBack,[=]({
//确保移动场景下一个场景位置一致
this->setGeometry(choose_pg->geometry());//继承选择页面的位置
this->show();
qDebug() << "show()";
});
}
//重写paintEvent()
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pix;
//画背景
pix.load(":/img/bg1.png");
painter.drawPixmap(0,0,this->width(),this->height(),pix);
}
Widget::~Widget()
{
delete ui;
}
4.关卡选择界面:choose_page.h/choose_page.cpp
-
choose_page.h
在这里时我遇到一个问题,如果不先声明class play_page;那么就会出现以下错误
#ifndef CHOOSE_PAGE_H
#define CHOOSE_PAGE_H
#include <QWidget>
#include <mypushbutton.h>
#include <play_page.h>
#include <game_data.h>
class play_page;
class choose_page : public QWidget
{
Q_OBJECT
public:
explicit choose_page(QWidget *parent =0);
//翻金币场景
play_page *pPage=NULL;
void paintEvent(QPaintEvent *);
signals:
void chooseSceneBack();//自定义信号,关闭自身
public slots:
};
#endif // CHOOSE_PAGE_H
-
choose_page.cpp
#include "choose_page.h"
#include <QTimer>
#include <QLabel>
#include <QString>
#include <QDebug>
#include <QPainter>
#include <QPixmap>
//绘制关卡选择页面
choose_page::choose_page(QWidget *parent) : QWidget(parent)
{
//配置框体大小
this->setFixedSize(350,600);
this->setStyleSheet("QPushButton{border:0px}"); //设置样式,无边框
this->setWindowTitle("选择关卡"); //设置标题
this->setWindowIcon(QIcon(":/img/lxh.png"));//左上角图标
//创建菜单栏(省略)
//选择关卡音效(省略)
//返回音效(省略)
//创建返回按钮
Mypushbutton *closebtn = new Mypushbutton(":/img/back1.png");
closebtn->setParent(this);//绑定父亲
closebtn->move(0,0);//调整组件的位置,左上角
//返回按钮的监听
connect(closebtn,&Mypushbutton::pressed,[&](){
//背景音乐play(省略)
QTimer::singleShot(100,this,[&](){//这个静态函数在一个给定时间间隔 msec(毫秒) 之后调用一个槽
this->hide();
emit this->chooseSceneBack();
});
});
//选择关卡按钮音效(省略)
//关卡按钮(写到这里的我头晕眼花)
for(int i=0;i<20;i++){
//创建关卡按钮
Mypushbutton *menubtn = new Mypushbutton(":/img/w.png");//图片
menubtn->setParent(this);
menubtn->move(50+(i%4)*70,130+(i/4)*70);//调整组件的位置
//创建数字标签
QLabel *lable = new QLabel;
lable->setParent(this);
lable->setFixedSize(menubtn->width(),menubtn->height());
lable->setText(QString::number(i+1));
lable->setAlignment(Qt::AlignCenter);
lable->move(50+(i%4)*70,130+(i/4)*70);
lable->setAttribute(Qt::WA_TransparentForMouseEvents,true);//鼠标穿透
/*当该属性被激活启用时,
* 将会使所有发送到窗体和窗体内部子控件的鼠标事件无效。
* 鼠标事件被分发到其它的窗体部件,
* 就像本窗体部件及本窗体内的子控件没有出现在窗体层次体系中。
* 鼠标单击和鼠标其它事件高效地穿过(即绕开)本窗体部件及其内的子控件,
* 这个属性默认是禁用未开启的。
*/
//关卡点击事件
connect(menubtn,&Mypushbutton::pressed,[=](){
qDebug() << "select" << i+1;
//选择音效play(省略)
//跳转到游戏场景
if(pPage==NULL){
this->hide();
pPage=new play_page(i+1);
//确保移动场景后下一个场景一致
pPage->setGeometry(this->geometry());
pPage->show();
//监听play_game自定义信号
connect(pPage,&play_page::chooseScenBack,[=](){
this->setGeometry(pPage->geometry());
this->show();
delete pPage;
pPage =NULL;
});
}
});
}
}
//重写绘图事件
void choose_page::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pix;
//画背景
pix.load(":/img/bg7.png");
painter.drawPixmap(0,0,this->width(),this->height(),pix);
}
5.准备游戏数据:game_data.h/game_data.cpp
-
game_data.h
#ifndef GAME_DATA_H
#define GAME_DATA_H
#include <QObject>
#include <QMap> //难道是传说中的hashmap
#include <QVector>
class game_data : public QObject
{
Q_OBJECT
public:
explicit game_data(QObject *parent = 0);
QMap<int ,QVector<QVector<int>>> mData;//数组
signals:
public slots:
};
#endif // GAME_DATA_H
-
game_data.cpp
数据我没有做任何改变。
#include "game_data.h"
#include <QDebug>
game_data::game_data(QObject *parent) : QObject(parent)
{
//1
int array1[4][4]={{1,1,1,1},
{1,1,0,1},
{1,0,0,0},
{1,1,0,1}};
QVector<QVector<int>> v;//QVector原来是数组的,对一个数组的封装,再封装一个数组就是二维数组。
for(int i=0;i<4;i++){
QVector<int>v1; //一维
for(int j=0;j<4;j++){
v1.push_back(array1[i][j]);// 把二维数组该位置的值给v1(一维)
}
//在把一个一维数据添加到一个一维数组里成为二维数组
v.push_back(v1);//push_back() 在Vector最后添加一个元素(参数为要插入的值)
}
mData.insert(1,v);//还真是键加值(二维数组),hash起来了
//2
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);
//3
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);
//4
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);
//5
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);
//6
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);
//7
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);
//8
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);
//9
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);
//10
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);
//11
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);
//12
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);
//13
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);
//14
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);
//15
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);
//16
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);
//17
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);
//18
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);
//19
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);
//20
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);
}
6.定义(金币):mycoin.h/mycoin.cpp
-
mycoin.h
#ifndef MYCOIN_H
#define MYCOIN_H
#include <QPushButton>
#include <QTimer>
#include <QString>
#include <QMouseEvent>
class mycoin : public QPushButton
{
Q_OBJECT
public:
//explicit mycoin(QWidget *parent = nullptr);
//重载构造 butimg代表图片路径
mycoin(QString butimg);
//改变标志,执行翻转效果
void changeFlag();
//重写按钮按下事件
void mousePressEvent(QMouseEvent *e);
//x坐标
int posX;
//y坐标
int posY;
//正反坐标
bool flag;
//正面翻反面定时器
QTimer *timer1;
//反面翻正面定时器
QTimer *timer2;
//胜利标志
bool isWin=false;
signals:
public slots:
};
#endif // MYCOIN_H
-
mycoin.cpp
#include "mycoin.h"
#include <QDebug>
#include <QPixmap>
#include "QPushButton"
mycoin::mycoin(QString butimg){
QPixmap pix;
bool ret=pix.load(butimg);
if(!ret)//判断图片
qDebug() << butimg << "mycoin加载图片失败";
//设置该对象属性
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 pixmap;
pixmap.load(":/img/q.png");
this->setFixedSize(pixmap.width(),pixmap.height());
this->setStyleSheet("QPushButton{border:0px;}");
this->setIcon(pixmap);
this->setIconSize(QSize(pixmap.width(),pixmap.height()));
timer1->stop();
});
//监听反面翻转的信号槽
connect(timer2,&QTimer::timeout,[=](){
QPixmap pixmap;
pixmap.load(":/img/bt2.png");
this->setFixedSize(pixmap.width(),pixmap.height());
this->setStyleSheet("QPushButton{border:0px;}");
this->setIcon(pixmap);
this->setIconSize(QSize(pixmap.width(),pixmap.height()));
timer2->stop();
});
}
//改变正反面的标志的方法
void mycoin::changeFlag(){
if(this->flag){
timer1->start(30);//一个0.03s执行一次的定时器
this->flag=false;
qDebug() << "zaima";
}else{
timer2->start(30);
this->flag=true;
}
}
//重写按钮按下事件
void mycoin::mousePressEvent(QMouseEvent *e){
if(this->isWin)
return;
else
return QPushButton::mousePressEvent(e);
}
7.游戏界面:play_page.h/paly_page.cpp
-
play_page.h
#ifndef PLAY_PAGE_H
#define PLAY_PAGE_H
#include <QWidget>
#include <mypushbutton.h>
#include <game_data.h>
#include <mycoin.h>
#include <QPropertyAnimation>
#include <choose_page.h>
class play_page : public QWidget
{
Q_OBJECT
public:
//explicit play_page(QWidget *parent = nullptr);
//重载鸟
play_page(int index);
//成员变量 记录关卡索引
int levelIndex;
//记录当前关卡的二维数组
int gameArray[4][4];
//金币按钮数组(新类)
mycoin *coinbtn[4][4];
//胜利标志
bool isWin=true;
void paintEvent(QPaintEvent *);
signals:
//自定义信号 关闭自身
void chooseScenBack();
public slots:
};
#endif // PLAY_PAGE_H
-
play_page.cpp
#include <choose_page.h>
#include "play_page.h"
#include <QDebug>
#include <QString>
#include <QTimer>
#include <QLabel>
#include <QString>
#include <QFont>
#include <QRect>
#include <QPropertyAnimation>
#include <QPainter>
#include <QMovie>
#include <QSound>//使用时需要在.pro文件里添加 QT += multimedia
//重载构造函数 index代表关卡数字
play_page::play_page(int index)
{
//设置窗口
qDebug() << "当前关卡为%d" << index;
this->levelIndex=index;
this->setFixedSize(350,600);
this->setStyleSheet("QPushButton{border:0px}");
QString str2=QString("关卡:%1").arg(this->levelIndex);//显示第几关
this->setWindowTitle(str2);
this->setWindowIcon(QIcon(":/img/lxh.png"));//左上角图标
//游戏音乐
QSound *bgSound = new QSound(":/img/bgsound.wav",this);//QSound得.wav才行
bgSound->play();//游戏音效play
//返回按钮
Mypushbutton *closebtn= new Mypushbutton(":/img/back1.png");
closebtn->setParent(this);
closebtn->move(0,0);//从该位置开始
connect(closebtn,&Mypushbutton::pressed,[=](){
QTimer::singleShot(500,this,[=](){//延时500ms
this->hide();
emit this->chooseScenBack();
qDebug() << "返回" << index;
});
});
//关卡显示
QLabel *lable= new QLabel;
lable->setParent(this);
QString str=QString("Level:%1").arg(this->levelIndex);//显示第几关
lable->setText(str);
lable->setGeometry(QRect(30,this->height()-50,120,50));
//初始化二维数组
game_data config;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
gameArray[i][j] =config.mData[this->levelIndex][i][j]; //记录当前关卡的二维数组
}
}
//胜利图片
QLabel* winLabel = new QLabel;
QPixmap tmpPix;
tmpPix.load(":/img/win.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());
//金币翻转
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
//半透明底座
QLabel *lable=new QLabel;
lable->setParent(this);
lable->setGeometry(0,0,50,50);
lable->setPixmap(QPixmap(":/img/w.png"));
lable->move(75+i*50,200+j*50);//标签在移动,就不会重叠
QString img;
if(gameArray[i][j]==1)
img=":/img/bt2.png";//正面
else
img=":/img/q.png";//反面
mycoin *coin=new mycoin(img);
coin->setParent(this);
coin->move(77+i*50,204+j*50);
coin->posX=i;
coin->posY=j;
coin->flag=gameArray[i][j];
coinbtn[i][j]=coin;
connect(coin,&mycoin::pressed,[=](){
coin->changeFlag();
gameArray[i][j] = gameArray[i][j] == 0 ? 1 : 0; //数组内部记录的标志同步修改
QTimer::singleShot(300, this,[=](){
if(coin->posX+1 <=3)//翻右侧金币
{
coinbtn[coin->posX+1][coin->posY]->changeFlag();
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]->changeFlag();
gameArray[coin->posX-1][coin->posY] = gameArray[coin->posX-1][coin->posY]== 0 ? 1 : 0;
}
if(coin->posY+1<=3)//翻下侧金币
{
coinbtn[coin->posX][coin->posY+1]->changeFlag();
gameArray[coin->posX][coin->posY+1] = gameArray[coin->posX+1][coin->posY]== 0 ? 1 : 0;
}
if(coin->posY-1>=0)//翻上侧金币
{
coinbtn[coin->posX][coin->posY-1]->changeFlag();
gameArray[coin->posX][coin->posY-1] = gameArray[coin->posX+1][coin->posY]== 0 ? 1 : 0;
}
//金币翻完了再解开矩阵
for(int i = 0 ; i < 4;i++)
{
for(int j = 0 ; j < 4; j++)
{
coinbtn[i][j]->isWin = false;
}
}
//判断是否胜利
this->isWin=true;
for(int i = 0 ; i < 4;i++)
{
for(int j = 0 ; j < 4; j++)
{
qDebug() << coinbtn[i][j]->flag ;
if( coinbtn[i][j]->flag == false)
{
this->isWin = false;
break;
}
}
}
if(this->isWin){
qDebug() << "win";
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
coinbtn[i][j]->isWin = true;
}
}
//胜利动画
QPropertyAnimation * animation1 = new QPropertyAnimation(winLabel,"geometry");
animation1->setDuration(1000);
animation1->setStartValue(QRect(winLabel->x(),winLabel->y(),winLabel->width(),winLabel->height()));
animation1->setEndValue(QRect(winLabel->x(),winLabel->y()+200,winLabel->width(),winLabel->height()));
animation1->setEasingCurve(QEasingCurve::OutBounce);
animation1->start();
}
});
});
}
}
}
//重载绘图事件
void play_page::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pix;
//画背景
pix.load(":/img/bg3.png");
painter.drawPixmap(0,0,this->width(),this->height(),pix);
}
![](https://img-blog.csdnimg.cn/2cc9a94f714e4643bd4ca23997215e37.gif)