cocos 3.2游戏暂停功能

时间:2021-04-17 20:09:09

<方法1>自写递归暂停类

1,GamePauseUtils.h

//
//  GamePauseUtils.h
//  AdventureKing
//
//  Created by jianan on 15/5/12.
//
//

#ifndef __AdventureKing__GamePauseUtils__
#define __AdventureKing__GamePauseUtils__

#include "cocos2d.h"
USING_NS_CC;

//操作类型
typedef enum OPERATE_TYPE{
    OPERATE_TYPE_PAUSE,
    OPERATE_TYPE_RESUME
}OPERATE_TYPE;


//
class GamePauseUtils
{
public:
    GamePauseUtils();
    ~GamePauseUtils();
    static GamePauseUtils* getInstance();
    void operateAllSchedulerAndActions(Node* node, OPERATE_TYPE type, int ignoreTag); //忽略检测的tag
};


#endif /* defined(__AdventureKing__GamePauseUtils__) */

2,GamePauseUtils.cpp

//
//  GamePauseUtils.cpp
//  AdventureKing
//
//  Created by jianan on 15/5/12.
//
//

#include "GamePauseUtils.h"

static GamePauseUtils* instance = NULL;

GamePauseUtils::GamePauseUtils(){
    
}

GamePauseUtils::~GamePauseUtils(){
    
}

GamePauseUtils* GamePauseUtils::getInstance(){
    if(instance == NULL){
        instance = new GamePauseUtils();
    }
    return instance;
}

void GamePauseUtils::operateAllSchedulerAndActions(Node* node, OPERATE_TYPE type, int ignoreTag){
    if(node->isRunning()){
        switch(type){
            case OPERATE_TYPE_PAUSE:
                node->pause();
                break;
            case OPERATE_TYPE_RESUME:
                node->resume();
                break;
        }
        
        
        Vector<Node*> array = node->getChildren();
        
        if(array.size() > 0){
            for(Vector<Node*>::iterator iter = array.begin(); iter != array.end();){
                Node* child = *iter;
                
                if(child->getTag() == ignoreTag){
                    iter++;
                }else{
                    iter++;
                    this->operateAllSchedulerAndActions(child, type, ignoreTag);
                }
            }
        }
    }
}
3,暂停
GamePauseUtils::getInstance()->operateAllSchedulerAndActions(rootLayer, OPERATE_TYPE_PAUSE, IGNORE_TAG);
4,恢复
 GamePauseUtils::getInstance()->operateAllSchedulerAndActions(rootLayer, OPERATE_TYPE_RESUME, IGNORE_TAG);


特点:适合所有情况,值需要把不需要暂停的节点用Tag标志即可。

<方法2>

Director::getInstance()->pause() 

特点:不常用,因为会关闭掉渲染。不友好。

<方法3>onExit与onEnter

class SecondScene : public Layer
{
public:
    static cocos2d::Scene* createScene();
    static Layer* createLayer(Node* pauseNode);
    virtual bool init();
    void menuCloseCallback1(cocos2d::Ref* pSender);
    CREATE_FUNC(SecondScene);
    Node* _pauseNode;
    
};

暂停

this->onExit();
Director::getInstance()->getRunningScene()->addChild(SecondScene::createLayer(this));


恢复
Layer* SecondScene::createLayer(Node* pauseNode)
{
    
    auto layer = SecondScene::create();
    layer->_pauseNode = pauseNode;
    return layer;
}

bool SecondScene::init()
{
    if (!Layer::init()){
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
        auto closeItem = MenuItemImage::create(
                                               "CloseNormal.png",
                                               "CloseSelected.png",
                                               CC_CALLBACK_1(SecondScene::menuCloseCallback1, this));
    
        closeItem->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2));
        auto menu = Menu::create(closeItem, NULL);
        menu->setPosition(Vec2::ZERO);
        this->addChild(menu, 1);
    
    return true;
}



void SecondScene::menuCloseCallback1(Ref* pSender){
    this->_pauseNode->onEnter();
    this->removeFromParent();
}
特点:同方法1,只是看起来更优雅一点
<方法4>pushScene与popScene

暂停

auto scene = SecondScene::createScene();
Director::getInstance()->pushScene(scene);


Scene* SecondScene::createScene()
{
    auto scene = Scene::create();
    auto layer = SecondScene::create();
    scene->addChild(layer);
    return scene;
}

恢复

Director::getInstance()->popScene();

特点:这种暂停其实是,新建了一个场景。覆盖到上面。

<方法5>推荐,大海战中用的

暂停

function NewBattleUILayer:onPauseGameClick( sender, eventType )
    if  eventType == ccui.TouchEventType.ended then
        GameScene.CurGameScene:pauseActionAndSchedule( true )
        cc.Director:getInstance():getRunningScene():addChild( BattlePauseLayer:create(), 777777 )
    end
end

恢复

function BattlePauseLayer:_soundStatusWriteFile()
    GameScene.CurGameScene:resumeActionAndSchedule()

    cc.UserDefault:getInstance():setBoolForKey( "isMusicClose", self.isMusicClose )
    cc.UserDefault:getInstance():flush()
    cc.UserDefault:getInstance():setBoolForKey( "isEffectClose", self.isEffectClose )
    cc.UserDefault:getInstance():flush()

    self:removeFromParent()
end