Qt5.12案例 翻金币小游戏

跟着做的参考视频: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

暂时没弄

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值