Cocos2d-x 用cocos2d-x实现MoonWarriors(暂停和恢复的实现)(转)
1.实现原理
原理不是通过调用 CCDirector::sharedDirector()->pause(),因为这个调用将会导致游戏彻底暂停,而无法返回运行状态!
而我们需要的是暂停的时候是游戏逻辑暂停,但是触摸事件监听不能停止,换句话说就是希望我们能控制哪一部分暂停,哪一部分不暂停。
有一种很繁琐的方法(看起来繁琐,代码不会很多),就是递归遍历需要暂停的层和精灵,调用pause()方法!
另一种简单的方法,就是调用需要暂停的层onExit()方法,这个方法在层中被复写了,其实就是删除重力加速的代理和按键代理。
- <span style="font-size:14px;">void CCLayer::onExit()
- {
- if( m_bIsTouchEnabled )
- {
- CCTouchDispatcher::sharedDispatcher()->removeDelegate(this);
- unregisterScriptTouchHandler();
- }
- // remove this layer from the delegates who concern Accelerometer Sensor
- if (m_bIsAccelerometerEnabled)
- {
- CCAccelerometer::sharedAccelerometer()->setDelegate(NULL);
- }
- // remove this layer from the delegates who concern the kaypad msg
- if (m_bIsKeypadEnabled)
- {
- CCKeypadDispatcher::sharedDispatcher()->removeDelegate(this);
- }
- CCNode::onExit();
- }
- </span>
<span style="font-size:14px;">void CCLayer::onExit() { if( m_bIsTouchEnabled ) { CCTouchDispatcher::sharedDispatcher()->removeDelegate(this); unregisterScriptTouchHandler(); } // remove this layer from the delegates who concern Accelerometer Sensor if (m_bIsAccelerometerEnabled) { CCAccelerometer::sharedAccelerometer()->setDelegate(NULL); } // remove this layer from the delegates who concern the kaypad msg if (m_bIsKeypadEnabled) { CCKeypadDispatcher::sharedDispatcher()->removeDelegate(this); } CCNode::onExit(); } </span>
2.我的实现
(1)暂停
自定义一个暂停层PauseLayer,在其init()方法中得到当前运行场景,遍历这个场景的子节点(一般都是层吧),调用子节点的onExit()方法即可!
- <span style="font-size:14px;">bool PauseLayer::init()
- {
- bool ret = false;
- do {
- CC_BREAK_IF(!CCLayerColor::initWithColor(ccc4f(255, 0, 0, 50)));
- CCArray *array = CCDirector::sharedDirector()->getRunningScene()->getChildren();
- CCObject *object = NULL;
- CCARRAY_FOREACH(array, object)
- {
- CCLayer *layer = (CCLayer*) object;
- layer->onExit();
- }
- ret = true;
- } while (0);
- return ret;
- }</span>
<span style="font-size:14px;">bool PauseLayer::init() { bool ret = false; do { CC_BREAK_IF(!CCLayerColor::initWithColor(ccc4f(255, 0, 0, 50))); CCArray *array = CCDirector::sharedDirector()->getRunningScene()->getChildren(); CCObject *object = NULL; CCARRAY_FOREACH(array, object) { CCLayer *layer = (CCLayer*) object; layer->onExit(); } ret = true; } while (0); return ret; }</span>
(2)恢复
我这里只是简单的在触屏开始的事件中恢复的,与onExit()调用相反,调用onEnter()就可以实现了!
- <span style="font-size:14px;">bool PauseLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
- {
- CCArray *array = CCDirector::sharedDirector()->getRunningScene()->getChildren();
- CCObject *object = NULL;
- CCARRAY_FOREACH(array, object)
- {
- CCLayer* layer = (CCLayer*) object;
- layer->onEnter();
- }
- this->removeFromParentAndCleanup(false);
- return true;
- }</span>