Qt入门系列(五)

2022-06-16 15:27:33 浏览数 (1)

文章首发在博主知乎


翻转金币场景设置

1.创建金币背景图案

在ps.cpp的构造函数中添加代码:

代码语言:javascript复制
 //显示金币背景图案
        for(int i=0;i<4;i  )
        {
            for(int j=0;j<4;j  )
            {
                //绘制背景图片
                QPixmap pix=QPixmap(":/res/BoardNode.png");
                QLabel* label=new QLabel;
                label->setGeometry(0,0,pix.width(),pix.height());
                label->setPixmap(pix);
                label->setParent(this);
                label->move(57 i*50,200 j*50);
            }
        }

结果显示:

2.添加金币类

新建一个class C : MyCoin,简称mc,继承QWidget ,将其修改为继承于QMyPushButton

在mc.cpp中添加实现:

代码语言:javascript复制
MyCoin::MyCoin(QString btnImg)
 {
     QPixmap pix;
     bool ret=pix.load(btnImg);
     if(!ret)
     {
         QString str=QString("图片加载失败").arg(btnImg);
         qDebug()<<str;
         return;
     }

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

在ps.cpp的构造函数中实例化:

代码语言:javascript复制
        //显示金币背景图案
        for(int i=0;i<4;i  )
        {
            for(int j=0;j<4;j  )
            {
                //绘制背景图片
                QPixmap pix=QPixmap(":/res/BoardNode.png");
                QLabel* label=new QLabel;
                label->setGeometry(0,0,pix.width(),pix.height());
                label->setPixmap(pix);
                label->setParent(this);
                label->move(57 i*50,200 j*50);

                //创建金币
                MyCoin *coin=new MyCoin(":/res/Coin0001.png");
                coin->setParent(this);
                coin->move(59 i*50,209 j*50);
            }
        }

结果显示:

3.每个关卡的默认实现

添加现有文件,把现有的dataconfig.h和dataconfig.cpp放在同一目录下,只有在父亲节点右键选择->添加现有文件->之后选择dataconfig.h和dataconfig.cpp,最后分成在头文件和源文件中生成了现有文件。

在ps.cpp的构造函数中添加代码:

代码语言:javascript复制

        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];
            }
        }
        //显示金币背景图案
        for(int i=0;i<4;i  )
        {
            for(int j=0;j<4;j  )
            {
                //绘制背景图片
                QPixmap pix=QPixmap(":/res/BoardNode.png");
                QLabel* label=new QLabel;
                label->setGeometry(0,0,pix.width(),pix.height());
                label->setPixmap(pix);
                label->setParent(this);
                label->move(57 i*50,200 j*50);

                //创建金币
                QString str;
                if(this->gameArray[i][j] == 0)
                {
                    //显示金币
                    str=":/res/Coin0001.png";
                }
                else
                {
                    //显示银币
                    str=":/res/Coin0008.png";
                }

                MyCoin *coin=new MyCoin(str);
                coin->setParent(this);
                coin->move(59 i*50,209 j*50);
            }
        }

结果显示:

4.金币翻转特效实现

在mc.cpp中定义实现

代码语言:javascript复制
MyCoin::MyCoin(QString btnImg)
 {
     QPixmap pix;
     bool ret=pix.load(btnImg);
     if(!ret)
     {
         QString str=QString("图片加载失败").arg(btnImg);
         qDebug()<<str;
         return;
     }

     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 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();
         }

     });

 }

 void MyCoin::changeFlag()
 {
     //如果是正面,翻成反面
     if(this->flag)
     {
         timer1->start(30);
         this->flag=false;
     }
     //反面翻正面
     else
     {
         timer2->start(30);
         this->flag=true;
     }
 }

在ps.cpp的构造函数中进行测试:

代码语言:javascript复制
 //显示金币背景图案
        for(int i=0;i<4;i  )
        {
            for(int j=0;j<4;j  )
            {
                //绘制背景图片
                QPixmap pix=QPixmap(":/res/BoardNode.png");
                QLabel* label=new QLabel;
                label->setGeometry(0,0,pix.width(),pix.height());
                label->setPixmap(pix);
                label->setParent(this);
                label->move(57 i*50,200 j*50);

                //创建金币
                QString str;
                if(this->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,209 j*50);

                //给金币属性赋值
                 coin->posX=i;
                 coin->posY=j;
                 coin->flag=this->gameArray[i][j];

                 //点击金币进行翻转
                 connect(coin,&MyCoin::clicked,[=](){
                     coin->changeFlag();
                 });

            }
        }

结果显示:

5.翻转周围硬币特效实现

在ps.cpp的构造函数中添加实现:

代码语言:javascript复制
  //显示金币背景图案
        for(int i=0;i<4;i  )
        {
            for(int j=0;j<4;j  )
            {
                //绘制背景图片
                QPixmap pix=QPixmap(":/res/BoardNode.png");
                QLabel* label=new QLabel;
                label->setGeometry(0,0,pix.width(),pix.height());
                label->setPixmap(pix);
                label->setParent(this);
                label->move(57 i*50,200 j*50);

                //创建金币
                QString str;
                if(this->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,209 j*50);

                //给金币属性赋值
                 coin->posX=i;
                 coin->posY=j;
                 coin->flag=this->gameArray[i][j];

                 coinBtn[i][j]=coin;

                 //点击金币进行翻转
                 connect(coin,&MyCoin::clicked,[=](){
                     coin->changeFlag();
                     this->gameArray[i][j]=this->gameArray[i][j]==0?1:0;

                     //翻转周围硬币
                     //延时翻转
                     QTimer::singleShot(300,this,[=](){
                         //周围右侧翻转
                        if(coin->posX 1<=3)
                        {
                            coinBtn[coin->posX 1][coin->posY]->changeFlag();
                            this->gameArray[coin->posX 1][coin->posY]=
                                    this->gameArray[coin->posX 1][coin->posY] == 0 ? 1:0;
                        }
                        //周围左侧
                        if(coin->posX-1>=0)
                        {
                            coinBtn[coin->posX-1][coin->posY]->changeFlag();
                             this->gameArray[coin->posX-1][coin->posY]=
                                    this->gameArray[coin->posX-1][coin->posY] == 0 ? 1:0;
                        }
                        //周围下侧
                        if(coin->posY-1 >= 0)
                        {
                            coinBtn[coin->posX][coin->posY-1]->changeFlag();
                             this->gameArray[coin->posX][coin->posY-1]=
                                    this->gameArray[coin->posX][coin->posY-1]==0?1:0;
                        }
                        //周围上册
                        if(coin->posY 1 <= 3)
                        {
                            coinBtn[coin->posX][coin->posY 1]->changeFlag();
                             this->gameArray[coin->posX][coin->posY 1]=
                                    this->gameArray[coin->posX][coin->posY 1]==0?1:0;
                        }
                     });

                 });

            }
        }

结果显示:

6.判断游戏是否胜利并禁止按钮

在ps.cpp的构造函数中添加实现:

代码语言:javascript复制
  //判断是否胜利
                        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()<<"游戏胜利";
                            //将所有胜利按钮改为true,直接return
                            for(int i=0;i<4;i  )
                            {
                                for(int j=0;j<4;j  )
                                {
                                       coinBtn[i][j]->isWin=true;
                                }
                            }


                        }

结果显示:

7.项目胜利图片实现

在ps.cpp的构造函数中添加:

代码语言:javascript复制
    //胜利图片显示
        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());
        
       .............................
       ...........................
        if(this->isWin == true)
                        {
                            //游戏胜利
                            qDebug()<<"游戏胜利";
                            //将所有胜利按钮改为true,直接return
                            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(1000);
                          //设置开始位置
                          animation->setStartValue(QRect(winLabel->x(),winLabel->y(),winLabel->width(),
                                                            winLabel->height()));
                          //设置结束位置
                          animation->setEndValue(QRect(winLabel->x(),winLabel->y() 114,winLabel->width(),
                                                       winLabel->height()));
                          //设置曲线
                          animation->setEasingCurve(QEasingCurve::OutBounce);
                          //执行动画
                          animation->start();
                        }

结果显示:

8.设置音效

在.pro中添加QT = core gui multimedia(帮助文档中搜到的)QSound的依赖

之后在mw.cpp中添加开始音效:

代码语言:javascript复制
   //增加开始按钮的音效
    QSound *startSound=new QSound(":/res/TapButtonSound.wav");
         startSound->play();

在cs.cpp中添加选择关卡的音效、返回的音效:

代码语言:javascript复制
    //增加选择关卡的音效
        QSound *chooseSound=new QSound(":/res/TapButtonSound.wav",this);
     //返回按钮
         QSound *backSound=new QSound(":/res/BackButtonSound.wav",this);

在ps.cpp中添加翻转金币的音效:

代码语言:javascript复制

        //返回按钮
            QSound *backSound=new QSound(":/res/BackButtonSound.wav",this);
            //翻金币
            QSound *flipSound=new QSound(":/res/ConFlipSound.wav",this);
             //胜利按钮
            QSound *winSound=new QSound(":/res/LevelWinSound.wav",this);

9.项目优化

场景位置固定不变

在mw.cpp中添加

代码语言:javascript复制
  //监听选择关卡的返回按钮
    connect(chooseScence,&ChooseLevelScence::chooseScenceBack,this,[=](){
        this->setGeometry(chooseScence->geometry());
        //将选择关卡场景 进行隐藏
         chooseScence->hide();
         this->show();//重新显示主场景
    });
    
    
    //进入选择关卡界面
        //延时进入到
        QTimer::singleShot(500,this,[=](){
            chooseScence->setGeometry(this->geometry());

            //自身隐藏
            this->hide();
            //显示选择关卡
            chooseScence->show();
        });

在cs.cpp中添加:

代码语言:javascript复制
 //设置游戏的初始位置
            play->setGeometry(this->geometry());
play->show();
            connect(play,&PlayScence::chooseScenceBack,[=](){

                this->setGeometry(play->geometry());
                this->show();
                delete play;
                play=NULL;
            });

项目成果: http://mpvideo.qpic.cn/0bf2dyaaiaaar4abtit3qrpfahwdaqpaabaa.f10002.mp4?dis_k=26debd174793a750d1182672b21f28f5&dis_t=1655364400&vid=wxv_1267259138875342849&format_id=10002&support_redirect=0&mmversion=false

10.项目发布

Windows下:

1.将Debug改成Release,生成编译,运行

此时生成一个Release文件,但是对方也要安装QT环境才能玩。

2.将Release中的CoinFlip.exe单独拷贝出来放在一个Game文件夹里,打开终端。

利用安装路径Qt/../../bin下的可执行文件进行打包:

windeployqt CoinFlip.exe

或者应用第三方打包程序软件

hm nis edit

最后生成一个安装包Setup.exe

Ubuntu下:

cnblogs.com/wanghuixi/p

第一步:将Release中的CoinFlip.exe单独拷贝出来放在一个Game文件夹里,打开终端。

编写一个脚本,将ldd CoinFlip.exe显示的链接库全部拷贝Game文件里:

dabao.sh

代码语言:javascript复制
#!/bin/sh
  
exe="/home/lyy/QTQTQT/build-CoinFlip-Desktop_Qt_5_10_0_GCC_64bit-Debug/CoinFlip" #发布的程序名称   这是我的可执行程序的名字
des="/home/lyy/QTQTQT/Game_CoinFlip/" #你的路径   这是我的可执行文件的路径 对应的相应的更改
  
deplist=$(ldd $exe | awk  '{if (match($3,"/")){ printf("%s "),$3 } }')
cp $deplist $des

第二步:编写运行脚本文档

运行脚本命名必须与可执行文件一致,CoinFlip.sh

代码语言:javascript复制
#!/bin/sh
    appname=`basename $0 | sed s,.sh$,,`
      
    dirname=`dirname $0`
    tmp="${dirname#?}"
      
    if [ "${dirname%$tmp}" != "/" ]; then
    dirname=$PWD/$dirname
    fi
    LD_LIBRARY_PATH=$dirname
    export LD_LIBRARY_PATH
    $dirname/$appname "$@"

给定权限

代码语言:javascript复制
chomd  x CoinFlip.sh

进行运行

代码语言:javascript复制
./CoinFlip.sh

笔记:

参考:黑马程序员

0 人点赞