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

2023-11-07

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

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT翻金币小游戏实现(三) 的相关文章

随机推荐

  • 【MySQL笔记】正确的理解MySQL的MVCC及实现原理

    MVCC多版本并发控制 如果觉得对你有帮助 能否点个赞或关个注 以示鼓励笔者呢 博客目录 先点这里 首先声明 MySQL 的测试环境是 5 7 前提概要 什么是 MVCC 什么是当前读和快照读 当前读 快照读和 MVCC 的关系 MVCC
  • 数字水印技术

    数字水印技术在信息安全中属于数字版权保护方面的技术 数字水印通过嵌入或附加数字信息到数字媒体中 可以追踪和证明数字媒体的来源 版权 真伪等 数字水印可以被用于防止盗版 保护知识产权 证明数字证据的真实性等应用场景 从而保障信息安全和维护合法
  • jQuery学习

    1 jQuery概述 1 1 JavaScript 库 JavaScript 库 即library 是一个封装好的特定的集合 方法和函数 从封装一大堆函数的角度理解库 就是在这个库中 封装了很多预先定义好的函数在里面 比如动画animate
  • BAJT 中高级 Java 面试题答案

    1 请问你做过哪些JVM优化 使用什么方法达到什么效果 vm调优主要也就是内存空间的分配 最终策略 提高系统性能 主要策略有 1 增加eden空间 让更多的对象留在年轻代 2 大对象直接放到老年代 以免扰乱年轻代高频率的gc XX Pete
  • 怎么查找电脑中的流氓软件_1个神器彻底删除流氓软件,瞬间清出十几个G,你的电脑有救了!...

    在使用电脑中 我们总会遇到一些流氓软件 不仅严重拖慢了电脑的运行速度 还不定时地弹出一个又一个的 定时炸弹 毋庸置疑 这些定时炸弹就是各种烦人的广告和弹窗了 尽管我们通过常规的方式把它卸载 但它还会卷土重来 那么对于那些卸载了仍会有文件残留
  • SpringCloud:SpringCloud生态的组成,组件的介绍(一)

    springCloud官方文档 https www springcloud cc 中文网 https spring io projects spring cloud 官方网 SpringCloud是什么 Spring Cloud是一个基于S
  • 一文读懂:区块链中的Merkle树

    我们知道 区块链中每个区块包括区块头和区块体两部分 个人技术公众号 解决方案工程师 欢迎同领域的朋友关注 相互交流 像在CSDN一样 分享技术 分享代码 分享方案文档 分享白皮书 区块体中包含了由区块链系统产生的一系列交易数据 并以Merk
  • SLAM入门

    SLAM定义 SLAM Simultaneous localization and mapping 同时定位 我在哪里 与建图 我周围有什么 当某种移动设备 汽车 扫地机 手机 无人机 机器人 从一个未知环境的未知地点出发 在运动过程中 通
  • P27 多表查询的分类:非等值连接、自连接、内、外连接

    3 多表查询的分类 7 多表查询的分类 角度1 等值连接 vs 非等值连接 角度2 自连接 vs 非自连接 角度3 内连接 vs 外连接 等值连接 vs 非等值连接 SELECT FROM job grades 非等值连接 薪资是在一个范围
  • airpods固件更新方法_AirPods2/AirPods Pro新固件怎么升级 固件更新方法

    17日上午 苹果公司发布了针对 AirPods 2 和 AirPods Pro 两款无线耳机的的固件更新 不过目前官方并未说明此次更新的具体改进 AirPods Pro 是苹果 10 月底推出的新品 支持主动降噪功能 在今天之前 它的固件版
  • MySQL数据库基本概念介绍

    MySQL数据库 一 数据库的简介 1 数据 Data 2 表 3 数据库 二 数据库的概念 1 数据库管理系统 DBMS 2 数据库系统 三 数据库的发展史 1 第一代数据库 2 第二代数据库 3 第三代数据库 四 当前主流数据库介绍 1
  • 搜索引擎solr系列---与java的springboot项目连接配置

    java与solr连接 调用查询的方式 我知道的有两种 solrj方式 这种方式写法较麻烦 倒不是因为难 就是简单的逻辑 有时候为了一个业务写一堆代码 所以solrj的这种方式还是比较灵活的 能实现你需要的变态业务需求 我发现它的一个小缺点
  • SpringBoot 3.x整合Fluent Mybatis极简流程

    此为基础配置 不包括其他高级配置 需要其他高级配置请查阅官方文档 fluent mybatis特性总览 Wiki Gitee com https gitee com fluent mybatis fluent mybatis wikis f
  • 软件测试学习路线

    下图是某培训机构的课程概要 同样的 我们学习的路线基本如此 下面主要总结一下 注意 因为自身原因 所以我的方案是自己的自学方案 仅作参考 1 测试基础知识 一些测试必备文档以及概念要掌握 这是最基本的 1 gt 测试分类 按测试技术划分为
  • 实验吧——加了料的报错注入

    coding utf8 import requests import re def denglu username password 设置代理 用于调试过程中抓包分析 proxies http http localhost 9008 htt
  • 了解文件的随机读写,文件类别、文件缓冲区,文件操作知识点补充(接上文)

    文件的操作 老规矩笔记自取 文件操作进阶笔记 欢迎喜欢学习C C 的朋友互关一起努力 文章目录 文件的操作 一 文件的随机读写 1 fseek 定位文件指针函数 2 ftell 当前偏移量函数 3 rewind 返回起始位置函数 二 文本文
  • java操作seaweedfs

    前置条件是seaweedfs服务已成功启动 具体部署可参考我上篇文章SeaweedFS部署及使用指南 首先导入pom依赖
  • Python Scrapy网络爬虫框架从入门到实战

    Python Scrapy是一个强大的网络爬虫框架 它提供了丰富的功能和灵活的扩展性 使得爬取网页数据变得简单高效 本文将介绍Scrapy框架的基本概念 用法和实际案例 帮助你快速上手和应用Scrapy进行数据抓取 Scrapy是一个基于P
  • SpringMVC源码总结 ViewResolver介绍

    首先我们先看看ModelAndView中重要的View接口 View接口 Java代码 String getContentType Render the view given the specified model p The first
  • QT翻金币小游戏实现(三)

    4 创建翻金币场景 4 1创建翻金币界面 设计好主场景以及选择关卡界面以后 就来到了最重要的一环 翻金币 首先还是创建一个cpp文件命名为PlayScene 第一步在选择关卡中声明PlayScene pScene NULL 方便后面使用 点