【QT】翻金币小游戏·我的学习版

  • 在学习QT的过程中,发现翻金币是一个很好的案例,故而学习,代码会有略微不同,是学习笔记。

目录

1.主函数main.cpp

2.自定义按钮:mypushbutton.h/mypushbutton.cpp

mypushbutton.h

mypushbutton.cpp

3.开始界面:widget.h/widget.cpp

widget.h

 widget.cpp

4.关卡选择界面:choose_page.h/choose_page.cpp

choose_page.h

 choose_page.cpp

5.准备游戏数据:game_data.h/game_data.cpp

game_data.h

game_data.cpp

6.定义(金币):mycoin.h/mycoin.cpp

mycoin.h

mycoin.cpp

7.游戏界面:play_page.h/paly_page.cpp

play_page.h

plsy_game.cpp


开始界面
选择界面
游戏界面

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;那么就会出现以下错误

我的解决办法: (15条消息) C++编译报错:does not name a type_Am最温柔的博客-CSDN博客https://blog.csdn.net/weixin_43919570/article/details/113833141

#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);


}

胜利动画效果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值