Cocos2d-x学习(十四):用cocos2d-x实现MoonWarriors(暂停和恢复的实现)

来源:互联网 发布:gamemaker mac 破解 编辑:程序博客网 时间:2024/05/23 00:48

特别声明:本文所有图片资源来源于MoonWarriors cocos2d-html 开源项目


今天搞了半天子弹发射这块,还是没弄完,我打算做一个子弹缓冲池,将所有子弹的图片资源打到同一个图片资源中,用一个CCSpriteBatchNode来绘制,这样在很多子弹的时候,就起到优化的效果了,CCSpriteBatchNode的原理是开启一次opengl绘制,绘制所有子精灵!


1.实现原理

原理不是通过调用 CCDirector::sharedDirector()->pause(),因为这个调用将会导致游戏彻底暂停,而无法返回运行状态!

而我们需要的是暂停的时候是游戏逻辑暂停,但是触摸事件监听不能停止,换句话说就是希望我们能控制哪一部分暂停,哪一部分不暂停。

有一种很繁琐的方法(看起来繁琐,代码不会很多),就是递归遍历需要暂停的层和精灵,调用pause()方法!

另一种简单的方法,就是调用需要暂停的层onExit()方法,这个方法在层中被复写了,其实就是删除重力加速的代理和按键代理。

[cpp] view plaincopy
  1. <span style="font-size:14px;">void CCLayer::onExit()  
  2. {  
  3.     if( m_bIsTouchEnabled )  
  4.     {  
  5.         CCTouchDispatcher::sharedDispatcher()->removeDelegate(this);  
  6.         unregisterScriptTouchHandler();  
  7.     }  
  8.   
  9.     // remove this layer from the delegates who concern Accelerometer Sensor  
  10.     if (m_bIsAccelerometerEnabled)  
  11.     {  
  12.         CCAccelerometer::sharedAccelerometer()->setDelegate(NULL);  
  13.     }  
  14.   
  15.     // remove this layer from the delegates who concern the kaypad msg  
  16.     if (m_bIsKeypadEnabled)  
  17.     {  
  18.         CCKeypadDispatcher::sharedDispatcher()->removeDelegate(this);  
  19.     }  
  20.   
  21.     CCNode::onExit();  
  22. }  
  23. </span>  
在最后调用了CCNode::onExit(),这个方法暂停了所有的schedule和action,这正是我们想要的结果!

[cpp] view plaincopy
  1. <span style="font-size:14px;">void CCLayer::onExit()  
  2. {  
  3.     if( m_bIsTouchEnabled )  
  4.     {  
  5.         CCTouchDispatcher::sharedDispatcher()->removeDelegate(this);  
  6.         unregisterScriptTouchHandler();  
  7.     }  
  8.   
  9.     // remove this layer from the delegates who concern Accelerometer Sensor  
  10.     if (m_bIsAccelerometerEnabled)  
  11.     {  
  12.         CCAccelerometer::sharedAccelerometer()->setDelegate(NULL);  
  13.     }  
  14.   
  15.     // remove this layer from the delegates who concern the kaypad msg  
  16.     if (m_bIsKeypadEnabled)  
  17.     {  
  18.         CCKeypadDispatcher::sharedDispatcher()->removeDelegate(this);  
  19.     }  
  20.   
  21.     CCNode::onExit();  
  22. }</span>  


2.我的实现

(1)暂停

自定义一个暂停层PauseLayer,在其init()方法中得到当前运行场景,遍历这个场景的子节点(一般都是层吧),调用子节点的onExit()方法即可!

[cpp] view plaincopy
  1. <span style="font-size:14px;">bool PauseLayer::init()  
  2. {  
  3.     bool ret = false;  
  4.       
  5.     do {  
  6.         CC_BREAK_IF(!CCLayerColor::initWithColor(ccc4f(255, 0, 0, 50)));  
  7.           
  8.         CCArray *array = CCDirector::sharedDirector()->getRunningScene()->getChildren();  
  9.         CCObject *object = NULL;  
  10.         CCARRAY_FOREACH(array, object)  
  11.         {  
  12.             CCLayer *layer = (CCLayer*) object;  
  13.             layer->onExit();  
  14.         }  
  15.           
  16.         ret = true;  
  17.     } while (0);  
  18.       
  19.     return ret;  
  20. }</span>  


(2)恢复

我这里只是简单的在触屏开始的事件中恢复的,与onExit()调用相反,调用onEnter()就可以实现了!

[cpp] view plaincopy
  1. <span style="font-size:14px;">bool PauseLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)  
  2. {  
  3.     CCArray *array = CCDirector::sharedDirector()->getRunningScene()->getChildren();  
  4.     CCObject *object = NULL;  
  5.     CCARRAY_FOREACH(array, object)  
  6.     {  
  7.         CCLayer* layer = (CCLayer*) object;  
  8.         layer->onEnter();  
  9.     }  
  10.       
  11.     this->removeFromParentAndCleanup(false);  
  12.       
  13.     return true;  
  14. }</span>  

效果如图



(左图为暂停状态,右图为运行状态)


项目地址

原创粉丝点击