(十八)C++自制植物大战僵尸游戏的游戏暂停实现

news/2024/5/3 18:21:25

植物大战僵尸游戏开发教程专栏地址icon-default.png?t=N7T8http://t.csdnimg.cn/uzrnw


游戏暂停

当玩家遇到突发事件,可以通过暂停功能暂停游戏,以便及时处理问题。在激烈的游戏中,玩家可能需要暂停游戏来进行策略调整。此外,长时间的游戏对战可能会让玩家感到疲劳,暂停功能可以让玩家短暂休息,调整状态,以便更好地进行后续的游戏。

代码文件位置

实现功能的代码在Class\Scenes\GameScene文件夹中。具体位置如下图所示 。


PauseQuitLayer.h 

这段代码定义了一个枚举类 PauseQuitLayer_Button,用于表示暂停退出图层中的按钮。

枚举类中定义了以下几个枚举值:

cpp

复制

enum class PauseQuitLayer_Button
{查看图鉴 = 0,重新开始,退出游戏,按键说明,返回游戏
};

每个枚举值都代表了暂停退出图层中的一个按钮,并具有与之对应的整数值。这些枚举值的含义如下:

  • 查看图鉴:表示一个按钮,用于查看游戏中的图鉴。
  • 重新开始:表示一个按钮,用于重新开始游戏。
  • 退出游戏:表示一个按钮,用于退出游戏。
  • 按键说明:表示一个按钮,用于显示按键说明。
  • 返回游戏:表示一个按钮,用于返回游戏继续进行。

使用这个枚举类可以方便地标识和操作暂停退出图层中的不同按钮,提高代码的可读性和维护性。


 

class GSPauseQuitLayer :public OptionsMenu
{
public:CREATE_FUNC(GSPauseQuitLayer);static Layer* addLayer();static void pauseLayer();static void resumeLayer();static int getPauseNumbers();CC_CONSTRUCTOR_ACCESS:GSPauseQuitLayer();~GSPauseQuitLayer();virtual bool init();protected:virtual void createButton(const Vec2& vec2, const std::string name, PauseQuitLayer_Button type);virtual void createDialog() override;virtual void popSceneAnimation();private:void showPrompt();void openHandBook();void setRestart();void setQuitGame();void keyDescription();void returnGame();protected:EventListenerTouchOneByOne* _touchListener;private:LayerColor* _promptLayer;static int _pauseNumbers;static string _layerName[6];char* _levelName;
};

这段代码定义了一个名为 GSPauseQuitLayer 的类,它是 OptionsMenu 类的子类。

这个类的主要特点和成员函数如下:

  • 类继承自 OptionsMenu,表示它是一个选项菜单类的扩展。

  • CREATE_FUNC(GSPauseQuitLayer) 是一个宏定义,用于创建 GSPauseQuitLayer 的实例。

  • addLayer() 是一个静态函数,返回一个 Layer* 类型的指针。

  • pauseLayer() 和 resumeLayer() 是静态函数,用于暂停和恢复图层的操作。

  • getPauseNumbers() 是静态函数,用于获取暂停次数。

  • GSPauseQuitLayer() 是构造函数。

  • ~GSPauseQuitLayer() 是析构函数。

  • init() 是一个虚函数,用于初始化图层的操作。

  • createButton() 是一个保护函数,用于创建按钮。

  • createDialog() 是一个重写的函数,用于创建对话框。

  • popSceneAnimation() 是一个保护函数,用于执行场景动画。

  • showPrompt()openHandBook()setRestart()setQuitGame()keyDescription() 和 returnGame() 是私有函数,用于处理不同按钮的点击事件。

  • _touchListener 是一个 EventListenerTouchOneByOne 类型的指针,用于监听触摸事件。

  • _promptLayer 是一个 LayerColor 类型的指针,用于显示提示信息的图层。

  • _pauseNumbers 是一个静态变量,表示暂停次数。

  • _layerName 是一个包含 6 个字符串的静态数组,表示图层的名称。

  • _levelName 是一个 char* 类型的指针,用于存储关卡名称。

该类提供了一些函数用于创建按钮、处理点击事件、执行动画等操作,并且具有一些静态变量用于记录暂停次数和图层名称。


PauseQuitLayer.cpp

构造函数

string GSPauseQuitLayer::_layerName[] = 
{ "backgroundLayer","buttonLayer","animationLayer","controlLayer","informationLayer","sunLayer" 
};int GSPauseQuitLayer::_pauseNumbers = 0;GSPauseQuitLayer::GSPauseQuitLayer() :_promptLayer(nullptr)
, _levelName(_global->userInformation->getCurrentCaveFileLevelWorldName())
{
}

这段代码给 GSPauseQuitLayer 类的静态成员变量 _layerName 和 _pauseNumbers 进行了初始化,并定义了 GSPauseQuitLayer 类的构造函数。

在这段代码中:

  • _layerName 是一个静态字符串数组,包含了 6 个图层的名称。

  • _pauseNumbers 是一个静态整数变量,用于记录暂停次数,初始值为 0。

  • GSPauseQuitLayer 类的构造函数 GSPauseQuitLayer() 初始化了成员变量 _promptLayer 为 nullptr,并将 _levelName 初始化为 _global->userInformation->getCurrentCaveFileLevelWorldName() 的返回值。这里使用了 _global 对象的 userInformation 成员指针来获取当前洞穴文件的级别世界名称。

通过这些代码,对 GSPauseQuitLayer 类的静态成员变量和构造函数进行了初始化,为后续的使用做好准备。


析构函数 

GSPauseQuitLayer::~GSPauseQuitLayer()
{_pauseNumbers = 0;
}

在析构函数中,将静态成员变量 _pauseNumbers 的值设置为 0。这意味着在销毁 GSPauseQuitLayer 对象时,会将暂停次数重置为 0。

这段代码的作用是在销毁 GSPauseQuitLayer 对象时,重置暂停次数,以便在下次使用时重新计数。


pauseLayer函数

void GSPauseQuitLayer::pauseLayer()
{auto director = Director::getInstance()->getRunningScene();for (auto name : _layerName){if (director->getChildByName(name))director->getChildByName(name)->onExit();elsereturn;}PlayMusic::stopMusic();++_pauseNumbers;
}

这个函数的作用是暂停图层的操作。具体的实现步骤如下:

  1. 获取当前正在运行的场景对象 director
  2. 遍历 _layerName 数组中的图层名称。
  3. 对于每个图层名称,检查是否存在对应的子节点。如果存在,则调用该子节点的 onExit() 函数进行退出操作。如果不存在任何一个图层,则直接返回。
  4. 调用 PlayMusic::stopMusic() 函数停止正在播放的音乐。
  5. 将暂停次数 _pauseNumbers 增加 1。

这段代码的功能是暂停图层,它会遍历图层名称数组并调用相应图层的退出操作,同时停止音乐播放并增加暂停次数。


resumeLayer函数 

void GSPauseQuitLayer::resumeLayer()
{if (!--_pauseNumbers){auto director = Director::getInstance()->getRunningScene();for (auto name : _layerName){if (director->getChildByName(name))director->getChildByName(name)->onEnter();elsereturn;}PlayMusic::resumeMusic();}
}

这个函数的作用是恢复图层的操作。具体的实现步骤如下:

  1. 检查暂停次数 _pauseNumbers 是否为 0。如果不为 0,则将暂停次数减 1。
  2. 如果暂停次数减少后为 0,则执行以下操作:
    • 获取当前正在运行的场景对象 director
    • 遍历 _layerName 数组中的图层名称。
    • 对于每个图层名称,检查是否存在对应的子节点。如果存在,则调用该子节点的 onEnter() 函数进行进入操作。如果不存在任何一个图层,则直接返回。
    • 调用 PlayMusic::resumeMusic() 函数恢复音乐播放。

这段代码的功能是恢复图层,它会根据暂停次数判断是否执行恢复操作,如果暂停次数为 0,则遍历图层名称数组并调用相应图层的进入操作,同时恢复音乐播放。


setRestart函数 

void GSPauseQuitLayer::setRestart()
{_director->getScheduler()->setTimeScale(1.0f);UserData::getInstance()->caveUserData("BREAKTHROUGH", ++_global->userInformation->getBreakThroughNumbers());_director->replaceScene(TransitionFade::create(1.0f, SelectPlantsScene::createScene()));UserData::getInstance()->createNewLevelDataDocument();UserData::getInstance()->removeLevelData(_levelName);
}

这个函数的作用是设置重新开始游戏的操作。具体的实现步骤如下:

  1. 使用 _director 对象的 getScheduler() 函数获取调度器对象,然后调用 setTimeScale(1.0f) 将时间缩放设置为正常速度。
  2. 使用 UserData::getInstance() 获取用户数据的实例,调用 caveUserData("BREAKTHROUGH", ++_global->userInformation->getBreakThroughNumbers()) 更新用户数据中的 "BREAKTHROUGH" 字段,将 BreakThroughNumbers 值加一。
  3. 使用 _director 对象的 replaceScene() 函数切换场景,将当前场景替换为 SelectPlantsScene 场景,并使用 TransitionFade::create(1.0f, SelectPlantsScene::createScene()) 创建一个淡入淡出的过渡效果。
  4. 使用 UserData::getInstance() 创建新的关卡数据文档。
  5. 使用 UserData::getInstance() 调用 removeLevelData(_levelName) 函数,从用户数据中移除指定关卡的数据,其中 _levelName 是当前关卡的名称。

这段代码的功能是执行重新开始游戏的操作。它重置播放速度,更新用户数据,切换场景,创建新的关卡数据文档,并移除当前关卡的数据。


setQuitGame函数 

void GSPauseQuitLayer::setQuitGame()
{_director->getScheduler()->setTimeScale(1.0f);UserData::getInstance()->caveUserData("BREAKTHROUGH", ++_global->userInformation->getBreakThroughNumbers());UserData::getInstance()->createNewLevelDataDocument();UserData::getInstance()->caveLevelData(_levelName);popSceneAnimation();
}

这个函数的作用是设置退出游戏的操作。具体的实现步骤如下:

  1. 使用 _director 对象的 getScheduler() 函数获取调度器对象,然后调用 setTimeScale(1.0f) 将时间缩放设置为正常速度。
  2. 使用 UserData::getInstance() 获取用户数据的实例,调用 caveUserData("BREAKTHROUGH", ++_global->userInformation->getBreakThroughNumbers()) 更新用户数据中的 "BREAKTHROUGH" 字段,将 BreakThroughNumbers 值加一。
  3. 使用 UserData::getInstance() 创建新的关卡数据文档。
  4. 使用 UserData::getInstance() 调用 caveLevelData(_levelName) 函数,将当前关卡的数据保存到用户数据中,其中 _levelName 是当前关卡的名称。
  5. 调用 popSceneAnimation() 函数执行退出游戏的过渡动画,弹出当前场景。

这段代码的功能是执行退出游戏的操作。它重置播放速度,更新用户数据,创建新的关卡数据文档,并保存当前关卡的数据,然后执行退出游戏的过渡动画,弹出当前场景。


createButton函数 

void GSPauseQuitLayer::createButton(const Vec2& vec2, const std::string name, PauseQuitLayer_Button button_type)
{/* 创建返回主菜单按钮 */auto button = ui::Button::create("ButtonNew2.png", "ButtonNew.png", "", TextureResType::PLIST);auto label = Label::createWithTTF(name, GAME_FONT_NAME_1, 35);label->enableShadow(Color4B(0, 0, 0, 200));//设置阴影label->setScale(2.0f);button->setTitleLabel(label);button->setTitleColor(Color3B::WHITE);button->setPosition(vec2);button->setScale(0.5f);_option->addChild(button);button->addTouchEventListener([=](Ref* sender, ui::Widget::TouchEventType type){switch (type){case ui::Widget::TouchEventType::BEGAN:PlayMusic::playMusic("gravebutton");break;case ui::Widget::TouchEventType::ENDED:switch (button_type){case PauseQuitLayer_Button::查看图鉴: openHandBook();   break;case PauseQuitLayer_Button::从新开始: setRestart();     break;case PauseQuitLayer_Button::退出游戏: setQuitGame();    break;case PauseQuitLayer_Button::按键说明: keyDescription(); break;case PauseQuitLayer_Button::返回游戏: returnGame();     break;default: break;}}});
}

这个函数用于创建按钮,并设置按钮的属性和触摸事件。具体的实现步骤如下:

  1. 创建一个按钮对象 button,使用图片资源 "ButtonNew2.png" 和 "ButtonNew.png",使用 TextureResType::PLIST 方式加载。
  2. 创建一个标签对象 label,使用字体文件 GAME_FONT_NAME_1 和字号 35。
  3. 设置标签的阴影效果,使用 enableShadow() 函数并传入阴影颜色 Color4B(0, 0, 0, 200)。
  4. 设置标签的缩放比例为 2.0。
  5. 将标签设置为按钮的标题标签,设置标题颜色为白色。
  6. 设置按钮的位置为 vec2
  7. 设置按钮的缩放比例为 0.5。
  8. 将按钮添加到 _option 节点中。
  9. 为按钮添加触摸事件回调函数,使用 addTouchEventListener() 函数。
  10. 在触摸事件回调函数中,根据触摸事件类型进行不同的处理:
    • 如果是触摸事件开始(BEGAN),播放 "gravebutton" 音效。
    • 如果是触摸事件结束(ENDED),根据按钮类型 button_type 执行相应的操作,包括打开图鉴、重新开始游戏、退出游戏、显示按键说明和返回游戏。

这段代码的功能是创建按钮并设置按钮的属性和触摸事件。根据按钮类型的不同,触摸事件的处理也不同,可以执行不同的操作。


其他函数 

其他函数不再一一解释,请自行查看理解。


http://www.mrgr.cn/p/70662406

相关文章

如何下载省,市,区县行政区Shp数据

摘要:一般非专业的GIS应用通常会用到省市等行政区区划边界空间数据做分析,本文简单介绍了如何在互联网上下载省,市,区县的shp格式空间边界数据,并介绍了一个好用的在线数据转换工具,并且开源。 目录 一、下…

牛客小白月赛91 (小白被虐记)

A.Bingbong的化学世界(签到题) 思路: 你会发现当 a[1][4] == . 是是 o-甲乙苯 a[6][4] == | 是是 p-甲乙苯 另外则是m-甲乙苯 Code:#include<bits/stdc++.h>using namespace std;const int N = 10;char a[N][N];int main() {ios::sync_with_stdio(false); cin.tie(0); …

优先队列 存 结构体--重载运算符

参考:priority_queue在结构体中的使用_priority_queue 结构体-CSDN博客

FTP客户端Transmit 5 for Mac中文激活版

Transmit 5是一款功能强大的Mac FTP客户端软件&#xff0c;它由Panic公司开发&#xff0c;为用户提供简单、高效的文件传输体验。 Transmit 5 for Mac中文激活版下载 Transmit 5支持多种传输协议&#xff0c;如FTP、SFTP、WebDAV和Amazon S3等&#xff0c;满足用户不同的文件传…

Transformer中的位置编码详解

什么是位置编码 位置编码概述 位置编码的目的是为了补充序列的位置信息&#xff0c;这是因为自注意力机制本身不包含位置的概念&#xff08;例如顺序信息&#xff09;。位置编码的具体作用是&#xff0c;对于不同的输入序列成分&#xff0c;赋予其不同的位置标识&#xff0c;确…

南昌航空大学-软件学院-23201117-方宗卫第一次blog作业

前言 本次blog总结前三次大作业以及对于写完作业之后的思考,主要是对于最后一题答卷系统的思路以及错误总结。 1.关于题量 对于作业来说,映入眼帘的肯定是题量。三次java的PTA大作业中,随着最后一题的难度的增加,前面题目的数量也会减少,因此题目量适中,单纯从题量来说,…

HarmonyOS NEXT应用开发之深色跑马灯案例

介绍 本示例介绍了文本宽度过宽时,如何实现文本首尾相接循环滚动并显示在可视区,以及每循环滚动一次之后会停滞一段时间后再滚动。 效果图预览使用说明: 1.进入页面,检票口文本处,实现文本首尾相接循环滚动,且在同一可视区,滚动完成之后,停滞一段时间后继续滚动。 实现…

[面向对象] 单例模式与工厂模式

单例模式 是一种创建模式&#xff0c;保证一个类只有一个实例&#xff0c;且提供访问实例的全局节点。 工厂模式 面向对象其中的三大原则&#xff1a; 单一职责&#xff1a;一个类只有一个职责&#xff08;Game类负责什么时候创建英雄机&#xff0c;而不需要知道创建英雄机要…

【jinja2】模板渲染

HTML文件 return render_template(index.html)h1: 一级标题 变粗变大(狗头 <

性能测试——性能测试-linux监控工具——Jmeter插件之ServerAgent服务器性能监控工具的安装和使用

安装插件 1、在Jmeter官网:https://jmeter-plugins.org/wiki/PluginsManager/下载插件管理器Plugins-manager.jar参考博客地址:https://blog.csdn.net/qq_45664055/article/details/105979481需要先安装java,设置环境变量: 123

菜品分类,做这个公共字段填充我真破防了

第一个小节不属于业务功能开发,偏向技术的 公共字段:在业务表中有很多相同的字段,例如创建人,创建时间,修改人,修改时间,在维护数据时候,都需给这些字段赋值,这样程序之中出现很多重复的代码 使用切面统一处理 枚举:可以标识当前操作的类型(insert或update) AOP:切…

yolov8目标检测 部署瑞芯微rk3588记录

1. 前置条件 本地电脑系统&#xff0c;ubuntu20.04 训练代码&#xff1a; 训练代码下载的ultralytics官方代码 SHA&#xff1a;6a2fddfb46aea45dd26cb060157d22cf14cd8c64 训练代码仅做数据修改&#xff0c;类别修改&#xff0c;代码结构未做任何修改 需要准备的代码&#…

Oracle数据库 :查询表结构脚本

查询脚本 &#xff1a; SELECT CASE WHEN a.column_id1 THEN a.TABLE_NAME ELSE END AS 表名, a.column_id AS 序号, a.column_name as 列名, REPLACE(comments, CHR(10), ) as 列说明, a.data_type || ( || a.data_length || ) as 数据类型, a.DATA_LENGTH AS 长度, a.DATA_…

8thWall vs. AR.js

对于熟悉 JavaScript、WebGL 和 HTML5 等 Web 技术的数字创作者来说&#xff0c;8th Wall 提供了功能丰富且强大的 AR 开发平台&#xff0c;尽管价格较高。 然而&#xff0c;新手开发人员和专注于基于标记的 AR 的开发人员可能会发现 AR.js 更易于使用且更经济实惠。 1、8th Wa…

【单调栈】力扣85.最大矩形

好久没更新了 ~ 我又回来啦&#xff01; 两个好消息&#xff1a; 我考上研了&#xff0c;收到拟录取通知啦&#xff01;开放 留言功能 了&#xff0c;小伙伴对于内容有什么疑问可以在文章底部评论&#xff0c;看到之后会及时回复大家的&#xff01; 前面更新过的算法&#x…

重构国内游戏账号登录系统的思考和实践

本期作者 背景 账号登录系统&#xff0c;作为游戏发行平台最重要的应用之一&#xff0c;在当前的发行平台的应用架构中&#xff0c;主要承载的是用户的账号注册、登录、实名、防沉迷、隐私合规、风控等职责。合规作为企业经营的生命线&#xff0c;同时&#xff0c;账号登录作为…

在线编辑器 CodeMirror

如何优雅的在网页显示代码 如果开发在线编辑器 引入资源&#xff1a; <link rel"stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.60.0/codemirror.min.css"><script src"https://cdnjs.cloudflare.com/ajax/libs/c…

AI极速批量换脸!Roop-unleashed下载介绍,可直播

要说AI换脸领域,最开始火的项目就是Roop了,Roop-unleashed作为Roop的嫡系分支,不仅继承了前者的强大基因,更是在功能上实现了重大突破与升级 核心特性 1、可以进行高精度的图片、视频换脸,还能实时直播换脸,换脸效果真实、自然 2、不仅支持N卡处理程序(cuda),还额外提…

AI大模型日报#0416:李飞飞《2024年人工智能指数报告》、Sora加入Adobe、李彦宏聊百度大模型之路

​导读&#xff1a; 欢迎阅读《AI大模型日报》&#xff0c;内容基于Python爬虫和LLM自动生成。目前采用“文心一言”生成了每条资讯的摘要。标题: 刚刚&#xff0c;李飞飞团队发布《2024年人工智能指数报告》&#xff1a;10大趋势&#xff0c;揭示AI大模型的“喜”与“忧” 摘…

uni-app如何生成骨架屏

为什么需要骨架屏&#xff1a;为了缓解用户打开程序时等待接口的焦虑情绪 1.打开微信开发者工具&#xff0c;找到模拟器中的页面信息&#xff0c;选择生成骨架屏 2.将生成的wxml代码复制到vscode&#xff0c;在index的components中新建一个vue文件&#xff0c;只需保留请求接口…