QT翻金币小游戏实现(三)

4、创建翻金币场景

4.1创建翻金币界面
设计好主场景以及选择关卡界面以后,就来到了最重要的一环:翻金币。首先还是创建一个cpp文件命名为PlayScene。第一步在选择关卡中声明PlayScene *pScene = NULL;方便后面使用。点击选择某一关卡按钮以后会跳入该场景,此时该场景需要显示出来,来选择关卡界面需要隐藏。第二步就是注视掉原来PlayScene.h中的构造函数,自己重回写一个构造函数,并写一个成员变量用于记录所选择的关卡数,具体的代码与结果如下:

//进入到了游戏场景
           this->hide();//选择关卡界面隐藏
           play = new PlayScene(i+1);//这是将选择哪一个关卡告诉play
           play->show();//某一关卡显示
PlayScene::PlayScene(int levelNum)
{
    
    
    QString str = QString("进入了第 %1 关").arg(levelNum);
    qDebug()<<str;
    this->levelIndex = levelNum;
}

在这里插入图片描述
4.2翻转金币的基本配置
结果出来以后,发现所有关卡的界面很丑,什么都没有,接着就是对它的一顿操作了,主要有:背景,图标、大小、标题以及返回按钮(返回到选择关卡页面)还有就是菜单栏。总之代码与前面的一样,这里不在赘述。直接看结果,如下:
在这里插入图片描述
4.3增加关卡标签
以上设置好以后,就要设置关卡标签。在playscene代码以及结果如下:

    QLabel *Label = new QLabel;
    Label->setParent(this);

    QFont font;
    font.setFamily("华文新魏");//关卡标签的字体
    font.setPointSize(20);//大小
    Label->setFont(font);

    QString str1 = QString("Level %1").arg(this->levelIndex);//关卡
    Label->setText(str1);
    Label->setGeometry(QRect(30,this->height()-50,120,50));//位置

在这里插入图片描述
4.4增加金币背景图片
创建金币的背景图片,在此放置金币。逻辑比较简单,用2个for循环实现,代码与结果为:

for(int i = 0 ; i < 4;i++)
        {
    
    
            for(int j = 0 ; j < 4; j++)
            {
    
    
               //绘制背景图片
                QLabel* label = new QLabel;
                label->setGeometry(0,0,50,50);
                label->setPixmap(QPixmap(":/res/BoardNode.png"));
                label->setParent(this);
                label->move(57 + i*50,200+j*50);
            }
        }

在这里插入图片描述
4.5封装金币类
4.5.1在背景上图片中增加金币
金币作为本游戏最重要的一部分,拥有点击、翻转的特效。因此将金币类封装在一个类中,称之为“MyCoin",专门用于金币功能的实现。首先实现金币翻转功能,其实金币翻转就是8张图片快速切换而实现的,在给翻转金币的时候给用户呈现的无非就是金币或者银币。因此注释掉原来的构造函数,自己重新写一个构造函数,参数是金币或者银币的路径MyCoin(QString coinpath);在MyCoin.cpp中实现,需要说明的是,由于金币翻转需要按下因此需要更改其父类为QPushButton,代码及结果为:
在这里插入图片描述
4.6引入关卡数据
接着就是创建每一个关卡的数据,需要引入关卡数据文件,文件中记录了关卡的二维数组的数据。右键点击.pro选择添加现有文件,选择dataConfig.hdataConfig.cpp文件就好。在公有接口可以看到QMap<int, QVector< QVector<int> > >mData;其中int代表关卡数,而QVector<QVector>则记录着关卡中的二维数组。需要说明的是QMap<key,T>容器,它提供了一个字典(或者说关联的数组),一个键映射到一个值。在公有接口处是的int就是对应的key,而QVector<QVector>就是对应的T,这样就比较好理解。
在playscene.h中声明一个成员变量int gameArray[4][4];,用于记录当前关卡的二维数据。然后在playscene.cpp初始化二维数组,接着根据数组中的数值(0或1)判断是金币还是银币。代码如下:

 //初始化每一个关卡的二维数组
    dataConfig config;
    for(int i=0;i<4;i++)
    {
    
    
        for(int j=0;j<4;j++)
        {
    
    
            this->gameArray[i][j] = config.mData[this->levelIndex][i][j];
            //后面就可以根据gameArray[i][j]中的数据决定是金币或者是银币了
        }
    }
分割///
  //创建金币 做一个判断:金币或者是银币
            QString str;
            if(gameArray[i][j]==1)
            {
    
    
                str = ":/res/Coin0001.png";//金币
            }
            else
            {
    
    
                 str = ":/res/Coin0008.png";//银币
            }
            MyCoin * coin = new MyCoin(str);
            coin->setParent(this);
            coin->move(59 + i*50,204+j*50);//金币放置的位置与金币背景的位置一样

在这里插入图片描述
4.7翻转金币
金币放上去以后就要实现金币的翻转,也就是按一下就反转成银币。首先在mycoin.h中定义币的属性包括x、y位置以及是否翻转了。然后声明翻转的函数void changFlag(); ,在此函数下创建2个定时器用于记录正面翻到反面与反面翻到正面,以及定义2个用于记录照片个数的成员变量(因为是8张照片的翻转效果)。

 void changFlag();
    QTimer timer1;//正面->反面的定时器
    QTimer timer2;//反面->正面的定时器
    
    int min=1;
    int max=8;

.cpp中实现为:

oid MyCoin::changFlag()//改变金币银币面的标志
{
    
    
    if(this->flag) //如果是金币面,执行下列代码
       {
    
    
           timer1->start(30);
           this->flag = false;
       }
       else //银币面执行下列代码
       {
    
    
           timer2->start(30);
           this->flag = true;
       }
}

然后在构造函数中做监听操作,做出反应并结束定时器。接着在playscene.cpp中监听金币按下操作,并改变币种状态。

//监听的是金币面翻银币面的信号
    connect(timer1,&QTimer::timeout,[=](){
    
    
        QPixmap pix;
        QString str = QString(":/res/Coin000%1").arg(this->min++);
        pix.load(str);

        this->setFixedSize(pix.width(),pix.height());
        this->setStyleSheet("QPushButton{border:0px;}");
        this->setIcon(pix);
        this->setIconSize(QSize(pix.width(),pix.height()));

        //如果翻转结束了,将min重置为1
        if(this->min>this->max)
        {
    
    
            this->min=1;
            timer1->stop();
        }
    });
    //监听的是银币面翻金币面的信号
    connect(timer2,&QTimer::timeout,[=](){
    
    
        QPixmap pix;
        QString str = QString(":/res/Coin000%1").arg(this->max--);
        pix.load(str);

        this->setFixedSize(pix.width(),pix.height());
        this->setStyleSheet("QPushButton{border:0px;}");
        this->setIcon(pix);
        this->setIconSize(QSize(pix.width(),pix.height()));

        //如果翻转结束了,将min重置为1
        if(this->max<this->min)
        {
    
    
            this->max=8;
            timer2->stop();
        }
    });
 //点击金币进行翻转
            connect(coin,&MyCoin::clicked,[=](){
    
    
                coin->changFlag();
                this->gameArray[i][j] = this->gameArray[i][j]==0?1:0;//改变币种的状态
            });

4.8翻转周围金币
以上分析就基本实现了金币翻银币,银币翻金币的操作。现在的问题就是按一下就只能翻转一个,而我们最终要实现的是按某一个金币周围的金币进行翻转。其实就是位置的改变罢了,比如要翻转左侧的金币就if(coin->posX+1<=3),其余的类似。代码与结果如下:

  //实现周围金币的翻转
                if(coin->posX+1<=3)//右侧翻转条件
                {
    
    
                   coinBtn[coin->posX+1][coin->poxY]->changFlag();
                   this->gameArray[coin->posX+1][coin->poxY] = this->gameArray[coin->posX+1][coin->poxY]==0?1:0;
                }
                if(coin->posX-1>0)//左侧翻转条件
                {
    
    
                   coinBtn[coin->posX-1][coin->poxY]->changFlag();
                   this->gameArray[coin->posX-1][coin->poxY] = this->gameArray[coin->posX-1][coin->poxY]==0?1:0;
                }
                if(coin->poxY+1<=3)//上侧翻转条件
                {
    
    
                   coinBtn[coin->posX][coin->poxY+1]->changFlag();
                   this->gameArray[coin->posX][coin->poxY+1] = this->gameArray[coin->posX][coin->poxY+1]==0?1:0;
                }
                if(coin->poxY-1>0)//下侧翻转条件
                {
    
    
                   coinBtn[coin->posX][coin->poxY-1]->changFlag();
                   this->gameArray[coin->posX][coin->poxY-1] = this->gameArray[coin->posX][coin->poxY-1]==0?1:0;
                }

在这里插入图片描述
4.9判断胜利并显示胜利图像
项目马上就结束了,接下来就是要判断胜利,并且显示胜利的标志。在playscene.h中加入判断是否胜利的标志,一开始就给true。当周围的金币否翻转结束后,判断是否成功。成功标志是:金币都翻转为银币。当胜利以后禁止任何一个金币翻转,具体的代码如下:

 //判断是否胜利了
                    this->isWin = true;
                    for(int i=0;i<4;i++)
                    {
    
    
                        for(int j=0;j<4;j++)
                        {
    
    
                            if(coinBtn[i][j]->flag==false)//只要有一个是反面则失败了
                            {
    
    
                                this->isWin = false;
                                break;
                            }
                        }
                    }
                    if(this->isWin==true)
                    {
    
    
                        qDebug()<<"胜利了";
                        if(this->isWin==true)
                    {
    
    
                        qDebug()<<"胜利了";
                        //将所有按钮的胜利标志设为true
                        for(int i=0;i<4;i++)
                        {
    
    
                            for(int j=0;j<4;j++)
                            {
    
    
                                coinBtn[i][j]->isWin=true;    
                            }
                        } 
                    }
                    }

//显示胜利的标志

QLabel* winLabel = new QLabel;
    QPixmap tmpPix;
    tmpPix.load(":/res/LevelCompletedDialogBg.png");
    winLabel->setGeometry(0,0,tmpPix.width(),tmpPix.height());
    winLabel->setPixmap(tmpPix);
    winLabel->setParent(this);
    winLabel->move( (this->width() - tmpPix.width())*0.5 , -tmpPix.height());
胜利的特效///

```cpp
if(this->isWin)
  {
    
    
                            qDebug() << "胜利";
                            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()+170,winLabel->width(),winLabel->height()));
                            animation1->setEasingCurve(QEasingCurve::OutBounce);
                            animation1->start();
                        }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/appup/article/details/116863027