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

植物大战僵尸游戏开发教程专栏地址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();
		else
			return;
	}
	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();
			else
				return;
		}
		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.mfbz.cn/a/557663.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

爬取微博评论数据

# -*- coding: utf-8 -*- import requests #用于发送请求并且拿到源代码 from bs4 import BeautifulSoup #用于解析数据 1.找到数据源地址并且分析链接 2.发送请求并且拿到数据 3.在拿到的数据中解析出需要的数据 4.存储数据 headers { "User-Agent": "…

ubunt18.04安装ROS2

本文无废话,实现了ubunt18.04 下ros2的安装,并且同时兼容ros和ros2 如果想完ros(1)的,请参考我的前一篇文章:ubunt18.04安装ROS避坑指南 参考: https://blog.csdn.net/cau_weiyuhu/article/deta…

Ubuntu20.04版本命令行设置挂载磁盘,并设置开机自动挂载

最近部署应用 系统是Ubuntu20.4版本的Linux系统,加了数据盘,需要格式化后挂载,记录下: Linux 数据盘挂载(采用 parted 分区工具)-格式化为 ext4 1. 初始化 Linux 数据盘 挂载数据盘后或者随实例创建时一并创建的数据盘&#xff…

【数学建模】最优旅游城市的选择问题:层次分析模型(含MATLAB代码)

层次分析法(The analytic hierarachy process,简称AHP)是一种常用的决策分析方法,其基本思路是将复杂问题分解为多个组成部分,然后对这些部分进行逐一评估和比较,最后得出最优解决方案。(例如&a…

Linux 5.10 Pstore 学习之(二) 原理学习

目录 编译框架模块初始化pstore子系统ramoops模块初始化实例化注册回调数据结构 pstore_blk模块pstore_zone模块 测试扩展调试 编译框架 目标结构 linux_5.10/fs/pstore/ ├── blk.c ├── ftrace.c ├── inode.c // 核心1 ├── internal.h ├── Kconfig ├── …

Vitis HLS 学习笔记--scal 函数-探究

目录 1. Vitis HLS重器-Vitis_Libraries 2. 初识scal() 3. 函数具体实现 3.1 变量命名规则 3.2 t_ParEntries解释 3.3 流类型详解 3.4 双重循环 4. 总结 1. Vitis HLS重器-Vitis_Libraries 在深入探索Vitis HLS(High-Level Synthesis)的旅程中&…

了解 containerd 中的 snapshotter,先从 native 开始

本文内容节选自 《containerd 原理剖析与实战》,本书正参加限时优惠内购,点击阅读原文,限时 69.9 元购买。 上一篇文章《一文了解 containerd 中的 snapshot》中,介绍了containerd 的 snapshot 机制,了解到 containerd…

64B/66B编码 自定义PHY层设计

一、前言 之前的一篇文章讲解了64B/66B的基本原理,本篇在基于64B/66B GT Transceiver的基础之上设计自定义PHY。基本框图如下。 二、GT Mdule GT Module就按照4个GT CHannel共享一个GT COMMON进行设置,如下图。要将例子工程中的GT COMMON取出&#xff…

3.4 海思SS928开发 - 烧写工具 - BurnTool Emmc 烧写

3.4 烧写工具 - BurnTool Emmc 烧写 BurnTool 工具提供了多种烧写方式,这里只介绍最常用的 烧写emmc方式。 环境准备 PC 与单板之间连接好调试串口以及网线。 将厂商提供的出厂镜像拷贝至 PC 硬盘上,解压后得到的文件如下: . ├── boot_…

解决Ubuntu安装NVIDIA显卡驱动导致的黑屏问题

前言 本文是在经历了3天内5次重装Ubuntu系统后写下的,根本原因就是这篇文章的主题——安装NVIDIA显卡驱动!写下本文是为了让自己今后不再出同样类型的错误,同时,给其他出现同样问题的人一些启发! 本文实例的电脑配置如…

WEB前端-笔记(二)

一、事件 1.1类型 focus 获取焦点事件 ipt.addEventListener("focus", () > {.log("") }) blue 失去焦点事件 ipt.addEventListener("blur", () > {console.log("") }) inout 文本输入事件 txt.addEventListener("i…

实在智能协办2024中国核能行业RPA数字员工专项培训会

2024年中国核能行业RPA数字员工专项培训会于4月16日-19日在杭州举办,由中国核能行业协会信息化专业委员会主办、实在智能承办。本次培训由理论讲解、技术深化和实际操作三部分组成,旨在帮助核能行业从业人员学习与掌握基于大模型的RPA技术应用&#xff0…

NVIDIA NCCL 源码学习(十四)- NVLink SHARP

背景 上节我们介绍了IB SHARP的工作原理,进一步的,英伟达在Hopper架构机器中引入了第三代NVSwitch,就像机间IB SHARP一样,机内可以通过NVSwitch执行NVLink SHARP,简称nvls,这节我们会介绍下NVLink SHARP如…

使用 Meta Llama 3 构建人工智能的未来

使用 Meta Llama 3 构建人工智能的未来 现在提供 8B 和 70B 预训练和指令调整版本,以支持广泛的应用 使用 Meta AI 体验 Llama 3 我们已将 Llama 3 集成到我们的智能助手 Meta AI 中,它扩展了人们完成工作、创造和与 Meta AI 联系的方式。通过使用 Meta AI 进行编码任务和解…

从零到一品牌电商私域流量代运营规划方案

【干货资料持续更新,以防走丢】 从零到一品牌电商私域流量代运营规划方案 部分资料预览 资料部分是网络整理,仅供学习参考。 PPT共50页(完整资料包含以下内容) 目录 私域运营方案: 一、项目背景与目标 - 开创数智化…

华为路由器基于接口限速

一、背景 ISP与企业内网通过华为路由器接入Internet时,当大量流量进入路由器时,可能会因为带宽不足产生拥塞,导致丢包,严重影响用户上网体验。对于此需要对网络流量进行限制,其方式通常有防火墙带宽策略、路由器基于接口限速等。 二、华为路由器基于接口限速方式 在路由…

Docker 部署 MongoDB 数据库

文章目录 官网地址docker 网络mongod.conf部署 MongoDB部署 mongo-expressdocker-compose.ymlMongoDB shell 官网地址 https://www.mongodb.com/zh-cn docker 网络 # 创建 mongo_network 网络 docker network create mongo_network # 查看网络 docker network list # 容器连…

RT-Thread在Win10下编译出现 unsupported pickle protocol: 5解决方案

调试背景: 在WIN10下编译RT-Thread源码:对象处理器平台是Microchip SAMA5D27-SOM1-EK评估板。 unsupported pickle protocol: 5 编译出现报错:ValueError : unsupported pickle protocol: 5 $ scons scons: Reading SConscript files ... Newlib ver…

MySQL:执行一条查询语句期间发生了什么?

MySQL的架构分为两层,Server 层和存储引擎层 server层负责建立连接、分析和执行SQL,MySQL,MySQL大多数的核心功能模块都在在这里实现,下图上半部分都是server层做的事情,另外,所有的内置函数(如…

在mini2440上编写linux应用程序、字符设备驱动程序的编写与编译

在mini2440上编写linux应用程序 结合前两篇的学习,一个linux操作系统已经在mini2440上运行起来了,结合交叉编译环境和nfs等工具,我们可以在mini2440上编写任何我们在linux系统编程中学到的应用程序。一个简要的多文件Makefile文件如下&#…
最新文章