跟着做的参考视频:B站视频——最新QT从入门到实战完整版|传智教育
视频下方有评论给出代码压缩包,可去参考。(我的和他们的并无差别,不过是学习记录罢了,以下可不看)
运行后存在问题:胜利进入下一关时页面闪现明显
操作过程:
1、新建项目,三个界面的窗口类都为mainwindow,可跟着视频逐步添加三个界面的c/h/ui文件,也可最开始添加。按键、金币、初始化数组这三个只有c/h文件。
2、创建资源文件(.qrc):
项目右击——Add new...——Qt——Qt Resource File——命名为res(添加目录一定要在项目目录下,默认是)——完成——Add Prefix——前缀可改,我没变——Add Files——在项目目录或项目目录的子文件夹中选取图片、音乐(可逐个添加,也可选取多张一起添加,这里是选取所有一起添加)——点击打开——运行则可看见所添加的资源。
3、三个界面实现过程如下:
(一)主界面 goldcoinmainwindow.c/h
1 界面初始化:窗口大小setFixedSize、窗口图标setWindowIcon、退出按钮实现
2 设置背景图片
3 游戏开始按钮添加:按钮图片、名称、位置、父窗口
3.1 新建按钮类,按钮初始化:大小setFixedSize、样式setStyleSheet、图标setIcon、图标大小setIconSize
3.2 设置特效:向下void zoomBottom();、向上void zoomTop();
向下:
创建动画对象 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() + 20,this->width(),this->height()));
设置缓和曲线,为弹跳效果animation->setEasingCurve(QEasingCurve::OutBounce);
执行动画animation->start();
向上同理
3.3 鼠标按下与释放设置
按下效果:按钮的大小setFixedSize、样式setStyleSheet、图标setIcon、图标大小setIconSize
并返回按钮按下事件,让主界面执行其他程序
释放效果:按钮的大小setFixedSize、样式setStyleSheet、图标setIcon、图标大小setIconSize
并返回按钮按下事件,让主界面执行其他程序
4 开始按钮按下与选择关卡界面绑定connect(startBn,&mypushbuttons::clicked,this,[=]{…….}
4.1 添加音效
4.2 执行特效,即调用按钮向上、向下函数
4.3 0.5秒后进入选择关卡界面、本界面关闭QTimer::singleShot(500,this,[=](){…….}
(1)隐藏本界面;
(2)设置选择关卡的显示位置和本界面一样;
(3)进入选择关卡界面;
(5)监听选择关卡界面的返回信号,显示本界面
goldcoinmainwindow.h——主界面h文件
#ifndef GOLDCOINMAINWINDOW_H
#define GOLDCOINMAINWINDOW_H
#include <QMainWindow>
#include <QIcon>
#include<QAction>
#include <QPainter>
#include<QPixmap>
#include <QPaintEvent>
#include "mypushbuttons.h"
#include "chooselevelscene.h"
#include <QPushButton>
#include <QDebug>
#include <QFile>
#include <QTimer>
#include <QSound>
QT_BEGIN_NAMESPACE
namespace Ui { class goldcoinMainWindow; }
QT_END_NAMESPACE
class goldcoinMainWindow : public QMainWindow
{
Q_OBJECT
public:
goldcoinMainWindow(QWidget *parent = nullptr);
~goldcoinMainWindow();
//弹跳特效
void zoomBottom();
void zoomTop();
public:
void initwindow();
void paintEvent(QPaintEvent *);
chooselevelscene * m_chooseScence = nullptr;
private:
Ui::goldcoinMainWindow *ui;
};
#endif // GOLDCOINMAINWINDOW_H
goldcoinmainwindow.c——主界面c文件
#include "goldcoinmainwindow.h"
#include "ui_goldcoinmainwindow.h"
goldcoinMainWindow::goldcoinMainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::goldcoinMainWindow)
{
ui->setupUi(this);
initwindow();
}
goldcoinMainWindow::~goldcoinMainWindow()
{
delete ui;
}
//初始化函数
void goldcoinMainWindow::initwindow()
{
setFixedSize(320,588);//固定大小
setWindowIcon(QIcon(":/new/prefix1/res/Coin0001.png"));//图标
connect(ui->actionquit,&QAction::triggered,this,[=](){
this->close();
});//退出按钮实现
//开始按钮
mypushbuttons * startBn =new mypushbuttons (":/new/prefix1/res/MenuSceneStartButton.png");
startBn->setParent(this);
startBn->setObjectName("my_index_button");
startBn->move((int)this->width() * 0.5 - startBn->width() * 0.5 , (int)this->height() * 0.7);
m_chooseScence = new chooselevelscene;
//监听选择场景的返回信号,执行操作
connect(m_chooseScence,&chooselevelscene::chooseBackCenario,this,[=](){
this->setGeometry(m_chooseScence->geometry());//主场景显示到选择场景的原位置
m_chooseScence->hide();
this->show();
});
//监听点击事件,执行特效
connect(startBn,&mypushbuttons::clicked,this,[=]{
QSound * startSound = new QSound(":/new/prefix1/res/TapButtonSound.wav",this);
startSound->play();
startBn->zoomBottom();//向下
startBn->zoomTop();//向上
QTimer::singleShot(500,this,[=](){
this->hide();//隐藏自己 显示关卡
m_chooseScence->setGeometry(this->geometry());//设置选择关卡的位置
m_chooseScence->show(); //进入到选择关卡的场景
//播放开始音效
});
});
}
//绘制背景
void goldcoinMainWindow::paintEvent(QPaintEvent *)
{
QPainter painter(this);//创建画家,指定绘图设备
QPixmap pix;//创建QPixmap对象
pix.load(":/new/prefix1/res/PlayLevelSceneBg.png");//加载图片
painter.drawPixmap(0,0,this->width(),this->height(),pix);//显示图片(背景图)
pix.load(":/new/prefix1/res/Title.png");//加载标题
pix=pix.scaled(pix.width()*0.5,pix.height()*0.5);//缩放图片
painter.drawPixmap(10,30,pix.width(),pix.height(),pix);//显示标题图片
}
mypushbuttons.h——按键文件(开始按键以及返回按键都要调用它,前面已经说过它的作用以及设计过程)
#ifndef MYPUSHBUTTONS_H
#define MYPUSHBUTTONS_H
#include <QWidget>
#include <QPushButton>
#include <QDebug>
#include <QPropertyAnimation>
class mypushbuttons : public QPushButton
{
Q_OBJECT
public:
mypushbuttons(QString normalImg,QString pressImg = "" );
//弹跳特效
void zoomBottom();
void zoomTop();
QString m_normalImg;//正常显示的图片
QString m_pressImg;//按下显示的图片
bool m_flag = false; //是否禁用按钮
void mouseReleaseEvent(QMouseEvent *ev);
void mousePressEvent(QMouseEvent *ev);
signals:
};
#endif // MYPUSHBUTTONS_H
mypushbuttons.c
#include "mypushbuttons.h"
mypushbuttons::mypushbuttons(QString normalImg,QString pressImg)
{
//成员变量保存图片路径
this->m_normalImg = normalImg;
this->m_pressImg = pressImg;
//能否正常加载图片
QPixmap pix;
bool ret = pix.load(m_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()));
}
//弹跳特效
void mypushbuttons::zoomBottom()
{
//创建动画对象
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() + 20,this->width(),this->height()));
//设置缓和曲线,为弹跳效果
animation->setEasingCurve(QEasingCurve::OutBounce);
//执行动画
animation->start();
}
void mypushbuttons::zoomTop()
{
//创建动画对象
QPropertyAnimation * animation = new QPropertyAnimation(this,"geometry");
//设置动画时间间隔,毫秒
animation->setDuration(200);
//设置起始位置
animation->setStartValue(QRect(this->x(),this->y()+20,this->width(),this->height()));
//设置结束位置
animation->setEndValue(QRect(this->x(),this->y(),this->width(),this->height()));
//设置缓和曲线,为弹跳效果
animation->setEasingCurve(QEasingCurve::OutBounce);
//执行动画
animation->start();
}
//鼠标按下
void mypushbuttons::mousePressEvent(QMouseEvent *ev)
{
if(this->m_pressImg != "")
{
QPixmap pix;
bool ret = pix.load(this->m_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()));
}
if(m_flag)
{
return;
}
//让父类执行其他内容
return QPushButton::mousePressEvent(ev);
}
void mypushbuttons::mouseReleaseEvent(QMouseEvent *ev)
{
if(this->m_pressImg != "")
{
QPixmap pix;
bool ret = pix.load(this->m_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()));
}
return QPushButton::mouseReleaseEvent(ev);
}
(二)选择关卡界面
1 窗口大小setFixedSize、窗口图标setWindowIcon、退出按钮实现
2 添加背景图片
3 返回按钮
3.1 定义、放置位置、添加音效
3.2 监听返回按钮的按下信号:设置定时器、设置音效、执行返回信号emit this->chooseBackCenario();
4 选择按键实现
4.1 按键图片、放置位置
4.2 按键上定义一个标签:显示按键序号、字体、大小
4.3 监听每个按钮的点击事件,进入下一个场景(按键按下的信号、执行操作)
添加音效
进入游戏关卡界面
监听游戏界面的返回情况
本界面位置显示在游戏关卡界面的原位置;
游戏关卡为空,不执行别的操作、停留在本界面;
监听游戏界面的胜利情况
本界面位置显示在游戏关卡界面的原位置;
20关之内,直接加载下一关;
chooselevelscene.h——选择关卡界面
#ifndef CHOOSELEVELSCENE_H
#define CHOOSELEVELSCENE_H
#include <QMainWindow>
#include <QTextStream>
#include <QFile>
#include <QPixmap>
#include <QPushButton>
#include <QPainter>
#include <QDebug>
#include <QTimer>
#include <QLabel>
#include <QSound>
#include "mypushbuttons.h"
#include "myplay.h"
namespace Ui {
class chooselevelscene;
}
class chooselevelscene : public QMainWindow
{
Q_OBJECT
public:
explicit chooselevelscene(QWidget *parent = nullptr);
~chooselevelscene();
//初始化函数
void mainInit();
//关卡按钮
void levelInit();
//信号和槽的初始化
void connectInit();
void paintEvent(QPaintEvent *);
QWidget *m_parent; //父类
mypushbuttons * backBtn; //返回按钮
myPlay *m_playScena = nullptr; //游戏窗口指针
private:
Ui::chooselevelscene *ui;
signals:
//写一个信号
void chooseBackCenario();
public slots:
void sotsPlaytoCloose();
void sotsGotoNext(int index);
};
#endif // CHOOSELEVELSCENE_H
chooselevelscene.c
#include "chooselevelscene.h"
#include "ui_chooselevelscene.h"
chooselevelscene::chooselevelscene(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::chooselevelscene)
{
ui->setupUi(this);
//页面初始化
mainInit();
//关卡选择初始化
levelInit();
}
chooselevelscene::~chooselevelscene()
{
delete ui;
}
//初始化的值
void chooselevelscene::mainInit()
{
//固定宽高
this->setFixedSize(320,588);
//设置应用图片
this->setWindowIcon(QPixmap(":/new/prefix1/res/Coin0001.png"));
//退出按钮实现
connect(ui->actionquit,&QAction::triggered,this,[=](){
this->close();
});
//返回按钮
backBtn = new mypushbuttons(":/new/prefix1/res/BackButton.png",":/new/prefix1/res/BackButtonSelected.png");
backBtn->setParent(this);
backBtn->move(this->width() - backBtn->width() , this->height() - backBtn->height());//放置在右下角
//监听返回按钮的按下信号,执行操作
connect(backBtn,&mypushbuttons::clicked,this,[=](){
QTimer::singleShot(500,this,[=](){
QSound * startSound1 = new QSound(":/new/prefix1/res/TapButtonSound.wav",this);
startSound1->play();
emit this->chooseBackCenario();//执行返回信号
});
});
}
//绘背景图
void chooselevelscene::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pix;
pix.load(":/new/prefix1/res/OtherSceneBg.png");
painter.drawPixmap(0,0,this->width(),this->height(),pix);
//画背景上的标题
pix.load(":/new/prefix1/res/Title.png");
painter.drawPixmap(this->width() * 0.5 - pix.width() * 0.5 , 30, pix.width() ,pix.height() ,pix);
}
void chooselevelscene::levelInit()
{
for(int i=0;i<20;i++)
{
mypushbuttons * menubtn =new mypushbuttons(":/new/prefix1/res/LevelIcon.png");
menubtn->setParent(this);
//25是总体和窗口的间距 70是每个间距
menubtn->move(25+i%4*70,130+i/4*70);
//监听每个按钮的点击事件,进入下一个场景
connect(menubtn,&mypushbuttons::clicked,this,[=](){
QSound * startSound1 = new QSound(":/new/prefix1/res/TapButtonSound.wav",this);
startSound1->play();
qDebug() << QString("你选择的是第 %1 关").arg(i + 1);
this->hide();
//选择的关卡号传给myPlay
this->m_playScena = new myPlay(i+1);
this->m_playScena->setGeometry(this->geometry());
this->m_playScena->show();
//监听游戏界面返回情况
connect(this->m_playScena,&myPlay::playtochoose,this,&chooselevelscene::sotsPlaytoCloose);
//监听游戏界面胜利情况
connect(this->m_playScena,&myPlay::gotoNext,this,&chooselevelscene::sotsGotoNext);
});
//在上面打上数字
QFont font;
font.setFamily("华文新魏");
font.setPointSize(15);
QLabel * label = new QLabel(this);
label->setFixedSize(menubtn->width(),menubtn->height());
label->setText(QString::number(i + 1));
label->setFont(font);
label->move(25 + i % 4 * 70 ,130 + i / 4 * 70);
label->setObjectName("my_label_text_center");
//垂直和水平居中
label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
//设置让鼠标进行穿透 51号属性
label->setAttribute(Qt::WA_TransparentForMouseEvents);
}
}
//接收游戏界面返回的信号和处理
void chooselevelscene::sotsPlaytoCloose()
{
this->setGeometry(m_playScena->geometry());
this->show();
delete m_playScena;
m_playScena = nullptr;
}
//游戏胜利的情况
void chooselevelscene::sotsGotoNext(int index)
{
if(index == 20)
{
this->setGeometry(m_playScena->geometry());
this->show();
delete m_playScena;
m_playScena = nullptr;
return;
}
QRect a = m_playScena->geometry();
delete m_playScena;
m_playScena = nullptr;
qDebug() << QString("你选择的是第 %1 关").arg(index + 1);
this->hide();
this->m_playScena = new myPlay(index+1);
this->m_playScena->show();
m_playScena->setGeometry(a);
//监听游戏界面返回情况
connect(this->m_playScena,&myPlay::playtochoose,this,&chooselevelscene::sotsPlaytoCloose);
//监听游戏界面胜利情况
connect(this->m_playScena,&myPlay::gotoNext,this,&chooselevelscene::sotsGotoNext);
}
(三)游戏关卡界面
1 初始化游戏关卡界面
1.1 窗口大小setFixedSize、窗口图标setWindowIcon、退出按钮实现
1.2 添加背景图片
1.3 返回按钮
a、定义、放置位置、添加音效
b、监听返回按钮的按下信号:设置定时器、设置音效、执行返回信号emit this->playtochoose();
1.4 左下角显示当前关卡数
1.5 设置胜利图片(不在本页面显示出来)
1.6 设置金币背景
1.7 金币显示
a、初始化每一关卡的金币二维数组
b、金币显示在游戏关卡界面
2 金币翻转
2.1 给金币属性赋值
2.2 所有按键设为禁用状态
2.3 翻转所点击的按键本身:状态改变、启用、翻转
设置金币翻转动画:正面状态改变成反面状态,执行定时器,加载过程图片
2.4 翻转四周
2.5 翻转结束将金币按钮设为可按状态
2.6 判断每个金币的状态是否都是正面,是则将所有金币设为禁用
2.7 胜利
所有按键设为禁用状态;
胜利图片掉下来
开启音效
发送开启下一关的信号
dataconfig.h——初始化个游戏界面的二维数组(dataconfig和coin可先不看,在myplay所需的时候再添加以及学习)
#ifndef DATACONFIG_H
#define DATACONFIG_H
#include <QObject>
#include <QMap>
#include <QVector>
class dataconfig : public QObject
{
Q_OBJECT
public:
explicit dataconfig(QObject *parent = nullptr);
QMap<int, QVector< QVector<int> > >mData;
signals:
};
#endif // DATACONFIG_H
dataconfig.c
#include "dataconfig.h"
dataconfig::dataconfig(QObject *parent) : QObject(parent)
{
QVector< QVector<int>> v;
int array1[4][4] = {{1, 1, 1, 1},
{1, 1, 0, 1},
{1, 0, 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(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);
}
mycoin.h——对金币进行设计和操作
#ifndef MYCOIN_H
#define MYCOIN_H
#include <QPushButton>
#include <QDebug>
#include <QTimer>
#include <QPixmap>
class mycoin : public QPushButton
{
Q_OBJECT
public:
explicit mycoin(QString msgbtn);
//金币的属性
int posX;//x 坐标
int posY;//y 坐标
bool flag;// 正反提示
//改变标志的方法
void changeFlag();
QTimer *time1;//正面翻反面的定时器
QTimer *time2;//反面翻正面的定时器
int min=1;//最小图片
int max=8;//最大图片
//执行动画的标志
bool isAnimation=false;
//重写按下和释放
void mousePressEvent(QMouseEvent *e);
// MyCoin * coinBtn[4][4];
bool isWin=false;
signals:
};
#endif // MYCOIN_H
mycoin.c
#include "mycoin.h"
mycoin::mycoin(QString msgbtn)
{
QPixmap pix;
bool ret =pix.load(msgbtn);
if(!ret)
return;
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton{border:0px;}");/*设置不规则图片样式*/
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
time1 = new QTimer(this);
time2 = new QTimer(this);
connect(time1,&QTimer::timeout,this,[=](){
QPixmap pix;
QString str = QString(":/new/prefix1/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;
isAnimation=false;//停止做动画
time1->stop();
}
});
connect(time2,&QTimer::timeout,this,[=](){
QPixmap pix;
QString str = QString(":/new/prefix1/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->min>this->max)
{
this->max=8;
isAnimation=false;//停止做动画
time2->stop();
}
});
}
void mycoin::mousePressEvent(QMouseEvent *e)
{
if(this->isAnimation || this->isWin)
{
return;
}
else
{
QPushButton::mousePressEvent(e);
}
}
//改变标志,执行翻转效果
void mycoin::changeFlag()
{
//如果是正面 翻成反面
if(this->flag)
{
time1->start(30);
isAnimation=true;//开始做动画
this->flag=false;
this->isWin=true;
}
else{//反面翻正面
time2->start(30);
isAnimation=true;//开始做动画
this->flag=true;
this->isWin=true;
}
}
myplay.h——游戏关卡设计
#ifndef MYPLAY_H
#define MYPLAY_H
#include <QMainWindow>
#include <QTextStream>
#include <QFile>
#include <QPixmap>
#include <QPushButton>
#include <QPainter>
#include <QDebug>
#include <QTimer>
#include <QLabel>
#include <QPropertyAnimation>
#include "mypushbuttons.h"
#include "mycoin.h"
#include "dataconfig.h"
namespace Ui {
class myPlay;
}
class myPlay : public QMainWindow
{
Q_OBJECT
public:
explicit myPlay(int index,QWidget *parent = nullptr);
~myPlay();
void mainInit();//初始化函数
mypushbuttons * backBtn; //返回按钮
mycoin * coinBtn[4][4];
int gameArray[4][4];//二维数组维护每关关卡的具体数据
int m_levelIndex;//内部成员属性 记录所选的关卡
bool m_isWin=false;//是否胜利的标志
void paintEvent(QPaintEvent *);
private:
Ui::myPlay *ui;
signals:
void playtochoose();//写一个信号
void gotoNext(int index);//下一关
};
#endif // MYPLAY_H
myplay.c
#include "myplay.h"
#include "ui_myplay.h"
#include <QSound>
myPlay::myPlay(int index,QWidget *parent) :
QMainWindow(parent),
ui(new Ui::myPlay)
{
ui->setupUi(this);
this->m_levelIndex = index;
mainInit();
}
myPlay::~myPlay()
{
delete ui;
}
void myPlay::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pix;
pix.load(":/new/prefix1/res/PlayLevelSceneBg.png");
painter.drawPixmap(0,0,this->width(),this->height(),pix);
//画背景上的标题
pix.load(":/new/prefix1/res/Title.png");
painter.drawPixmap(this->width() * 0.5 - pix.width() * 0.5 , 30, pix.width() ,pix.height() ,pix);
}
//页面显示
void myPlay:: mainInit()
{
QString str =QString("进入了第 %1 关").arg(m_levelIndex);
qDebug()<<str;
this->setFixedSize(320,588);
this->setWindowIcon(QPixmap(":/new/prefix1/res/Coin0001.png"));
this->setWindowTitle("翻金币场景");
connect(ui->actionquit,&QAction::triggered,this,[=](){
this->close();
});
//1、显示返回按钮
backBtn = new mypushbuttons(":/new/prefix1/res/BackButton.png",":/new/prefix1/res/BackButtonSelected.png");
backBtn->setParent(this);
backBtn->move(this->width() - backBtn->width() , this->height() - backBtn->height());//放置在右下角
//监听返回按钮的按下信号,执行操作
connect(backBtn,&mypushbuttons::clicked,this,[=](){
QSound * startSound1 = new QSound(":/new/prefix1/res/TapButtonSound.wav",this);
startSound1->play();
QTimer::singleShot(500,this,[=](){
emit this->playtochoose();//执行返回信号
});
});
//2、显示当前关卡数
QLabel * label = new QLabel(this);
QFont font;
font.setFamily("华文新魏");
font.setPointSize(20);
label->setFont(font);
label->setText(QString("level:%1").arg(m_levelIndex));
label->setGeometry(30,this->height()-50,120,50);
//4、初始化每个关卡的二维数组
dataconfig config;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
this->gameArray[i][j]= config.mData[this->m_levelIndex][i][j];
}
}
QLabel * winlabel =new QLabel;
QPixmap tmppix;
tmppix.load(":/new/prefix1/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());
QSound * startSound1 = new QSound(":/new/prefix1/res/ConFlipSound.wav",this);
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
//3、显示金币背景图片
QPixmap pix = QPixmap(":/new/prefix1/res/BoardNode.png");
QLabel * label1 = new QLabel;
label1->setGeometry(0,0,pix.width(),pix.height());// 从窗体的(0,0)位置开始(即为最左上角的点),显示一个pix.width()*pix.height()的控件
label1->setPixmap(pix);//QLabel控件使用setPixmap函数显示图片
label1->setParent(this);//它的作用是为一个物体指定一个新的父窗体
label1->move(57+i*50,200+j*50);
//5、金币显示
QString str;
if(this->gameArray[i][j]==1)
{
str = ":/new/prefix1/res/Coin0001.png";
}
else
{
str =":/new/prefix1/res/Coin0008.png";
}
mycoin * m_coin = new mycoin(str);
m_coin->setParent(this);
m_coin->move(59+i*50,204+j*50);
//6、给金币属性赋值
m_coin->posX=i;
m_coin->posY=j;
m_coin->flag=this->gameArray[i][j];
//将金币放入到金币的二维数组里面
coinBtn[i][j]=m_coin;
//点击金币,进行翻转
connect(m_coin,&mycoin::clicked,this,[=](){
startSound1->play();
//在翻转金币的时候禁用其他按钮
for(int i = 0 ; i < 4; i++)
{
for(int j = 0 ; j < 4 ; j++)
{
this->coinBtn[i][j]->isWin = true;
}
}
//翻转本身
m_coin->changeFlag();
this->gameArray[i][j]=this->gameArray[i][j]==0?1:0;
QTimer::singleShot(100,this,[=](){
//翻转四周
if(m_coin->posX<3)
{
coinBtn[m_coin->posX+1][m_coin->posY]->changeFlag();
this->gameArray[m_coin->posX+1][m_coin->posY]=this->gameArray[m_coin->posX+1][m_coin->posY]==0?1:0;
}
if(m_coin->posX>0)
{
coinBtn[m_coin->posX-1][m_coin->posY]->changeFlag();
this->gameArray[m_coin->posX-1][m_coin->posY]=this->gameArray[m_coin->posX-1][m_coin->posY]==0?1:0;
}
if(m_coin->posY<3)
{
coinBtn[m_coin->posX][m_coin->posY+1]->changeFlag();
this->gameArray[m_coin->posX][m_coin->posY+1]=this->gameArray[m_coin->posX][m_coin->posY+1]==0?1:0;
}
if(m_coin->posY>0)
{
coinBtn[m_coin->posX][m_coin->posY-1]->changeFlag();
this->gameArray[m_coin->posX][m_coin->posY-1]=this->gameArray[m_coin->posX][m_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->m_isWin=true;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(coinBtn[i][j]->flag==false)
{
this->m_isWin=false;
break;
}
}
}
if(this->m_isWin==true)
{
this->backBtn->m_flag = true;
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(2000);
animation->setStartValue(QRect(winlabel->x(),winlabel->y(),winlabel->width(),winlabel->height()));
animation->setEndValue(QRect(winlabel->x(),winlabel->y()+200,winlabel->width(),winlabel->height()));
animation->setEasingCurve(QEasingCurve::OutBounce);
animation->start();
QSound * soud1 = new QSound(":/new/prefix1/res/LevelWinSound.wav",this);
soud1->play();
QTimer::singleShot(3000,this,[=](){
this->backBtn->m_flag = false;
soud1->stop();
//发送一个申请下一关的信号
emit gotoNext(m_levelIndex);
});
}
});
});
}
}
}
(四)代码上传gitee
暂时没弄