植物大战僵尸游戏开发教程专栏地址http://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;
}
这个函数的作用是暂停图层的操作。具体的实现步骤如下:
- 获取当前正在运行的场景对象
director
。- 遍历
_layerName
数组中的图层名称。- 对于每个图层名称,检查是否存在对应的子节点。如果存在,则调用该子节点的
onExit()
函数进行退出操作。如果不存在任何一个图层,则直接返回。- 调用
PlayMusic::stopMusic()
函数停止正在播放的音乐。- 将暂停次数
_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();
}
}
这个函数的作用是恢复图层的操作。具体的实现步骤如下:
- 检查暂停次数
_pauseNumbers
是否为 0。如果不为 0,则将暂停次数减 1。- 如果暂停次数减少后为 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);
}
这个函数的作用是设置重新开始游戏的操作。具体的实现步骤如下:
- 使用
_director
对象的getScheduler()
函数获取调度器对象,然后调用setTimeScale(1.0f)
将时间缩放设置为正常速度。- 使用
UserData::getInstance()
获取用户数据的实例,调用caveUserData("BREAKTHROUGH", ++_global->userInformation->getBreakThroughNumbers())
更新用户数据中的 "BREAKTHROUGH" 字段,将BreakThroughNumbers
值加一。- 使用
_director
对象的replaceScene()
函数切换场景,将当前场景替换为SelectPlantsScene
场景,并使用TransitionFade::create(1.0f, SelectPlantsScene::createScene())
创建一个淡入淡出的过渡效果。- 使用
UserData::getInstance()
创建新的关卡数据文档。- 使用
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();
}
这个函数的作用是设置退出游戏的操作。具体的实现步骤如下:
- 使用
_director
对象的getScheduler()
函数获取调度器对象,然后调用setTimeScale(1.0f)
将时间缩放设置为正常速度。- 使用
UserData::getInstance()
获取用户数据的实例,调用caveUserData("BREAKTHROUGH", ++_global->userInformation->getBreakThroughNumbers())
更新用户数据中的 "BREAKTHROUGH" 字段,将BreakThroughNumbers
值加一。- 使用
UserData::getInstance()
创建新的关卡数据文档。- 使用
UserData::getInstance()
调用caveLevelData(_levelName)
函数,将当前关卡的数据保存到用户数据中,其中_levelName
是当前关卡的名称。- 调用
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;
}
}
});
}
这个函数用于创建按钮,并设置按钮的属性和触摸事件。具体的实现步骤如下:
- 创建一个按钮对象
button
,使用图片资源 "ButtonNew2.png" 和 "ButtonNew.png",使用 TextureResType::PLIST 方式加载。- 创建一个标签对象
label
,使用字体文件 GAME_FONT_NAME_1 和字号 35。- 设置标签的阴影效果,使用 enableShadow() 函数并传入阴影颜色 Color4B(0, 0, 0, 200)。
- 设置标签的缩放比例为 2.0。
- 将标签设置为按钮的标题标签,设置标题颜色为白色。
- 设置按钮的位置为
vec2
。- 设置按钮的缩放比例为 0.5。
- 将按钮添加到
_option
节点中。- 为按钮添加触摸事件回调函数,使用
addTouchEventListener()
函数。- 在触摸事件回调函数中,根据触摸事件类型进行不同的处理:
- 如果是触摸事件开始(BEGAN),播放 "gravebutton" 音效。
- 如果是触摸事件结束(ENDED),根据按钮类型
button_type
执行相应的操作,包括打开图鉴、重新开始游戏、退出游戏、显示按键说明和返回游戏。这段代码的功能是创建按钮并设置按钮的属性和触摸事件。根据按钮类型的不同,触摸事件的处理也不同,可以执行不同的操作。
其他函数
其他函数不再一一解释,请自行查看理解。