That’s similar to me Tim.
I better share mine as well as it may benefit others who read this stuff.
Note: My structure is that I have a single scene that consists of multiple layers. I have gameplay-layer, hud-layer, hudcontrol-layer, and pause-layer. In gameplay-layer, it’s just like a container that hold other game objects in game session ie. enemies, hero, etc. Hud-layer consists of anything just to show for info but with no interaction. HudControl-layer is the main interaction that users will play with, it accepts touch events to control hero character, it has CCMenu* related class as well. Pause-layer is what I want to show when touch on pause button in hudcontrol-layer.
— Structure —
Root
|__ Scene
|__ Game Layer
|__ Hud Layer
|__ HudControl Layer
|__ Pause Layer
Utility class
The following is the implementation code inside Utility class. It’s a singleton class that accommodate me in notable things to easily code stuff.
Please note that
getGamePlayScene()
as seen below will return gameplay scene but the scene itself consists of gameplay-layer.
void ZHUtil::pauseScheduleAndActionsForAllLayers()
{
ZHUtil::sharedInstance()->getGameplayScene()->pauseSchedulerAndActions();
ZHUtil::sharedInstance()->getGameplayScene()->getStageLayer()->pauseSchedulerAndActions();
ZHUtil::sharedInstance()->getGameplayScene()->getHUDLayer()->pauseSchedulerAndActions();
ZHUtil::sharedInstance()->getGameplayScene()->getHUDControlLayer()->pauseSchedulerAndActions();
CCMenu* menu = (CCMenu*)ZHUtil::sharedInstance()->getGameplayScene()->getHUDControlLayer()->getChildByTag(MENU);
if(menu != NULL)
{
menu->setEnabled(false);
}
}
void ZHUtil::resumeScheduleAndActionsForAllLayers()
{
ZHUtil::sharedInstance()->getGameplayScene()->resumeSchedulerAndActions();
ZHUtil::sharedInstance()->getGameplayScene()->getStageLayer()->resumeSchedulerAndActions();
ZHUtil::sharedInstance()->getGameplayScene()->getHUDLayer()->resumeSchedulerAndActions();
ZHUtil::sharedInstance()->getGameplayScene()->getHUDControlLayer()->resumeSchedulerAndActions();
CCMenu* menu = (CCMenu*)ZHUtil::sharedInstance()->getGameplayScene()->getHUDControlLayer()->getChildByTag(MENU);
if(menu != NULL)
{
menu->setEnabled(true);
}
}
void ZHUtil::pauseScheduleAndActionsForAllEnemies()
{
CCArray* enemies = ObjectSpawner::sharedInstance()->getEnemies();
for(int i=0; icount(); i++)
{
CharacterAI* ai = (CharacterAI*)enemies->objectAtIndex(i);
ai->pauseSchedulerAndActions();
}
}
void ZHUtil::resumeScheduleAndActionsForAllEnemies()
{
CCArray* enemies = ObjectSpawner::sharedInstance()->getEnemies();
for(int i=0; icount(); i++)
{
CharacterAI* ai = (CharacterAI*)enemies->objectAtIndex(i);
ai->resumeSchedulerAndActions();
}
}
void ZHUtil::disableTouchForAllLayers()
{
ZHUtil::sharedInstance()->getGameplayScene()->setTouchEnabled(false);
ZHUtil::sharedInstance()->getGameplayScene()->getStageLayer()->setTouchEnabled(false);
ZHUtil::sharedInstance()->getGameplayScene()->getHUDLayer()->setTouchEnabled(false);
ZHUtil::sharedInstance()->getGameplayScene()->getHUDControlLayer()->setTouchEnabled(false);
}
void ZHUtil::enableTouchForAllLayers()
{
ZHUtil::sharedInstance()->getGameplayScene()->setTouchEnabled(true);
ZHUtil::sharedInstance()->getGameplayScene()->getStageLayer()->setTouchEnabled(true);
ZHUtil::sharedInstance()->getGameplayScene()->getHUDLayer()->setTouchEnabled(true);
ZHUtil::sharedInstance()->getGameplayScene()->getHUDControlLayer()->setTouchEnabled(true);
}
GameplayScene
Look at the following Pause/Resume method
void GameplayScene::pauseGame()
{
// pause schedule and actions
ZHUtil::sharedInstance()->pauseScheduleAndActionsForAllLayers();
ZHUtil::sharedInstance()->pauseScheduleAndActionsForAllEnemies();
m_kiki->pauseSchedulerAndActions();
// disable touch
ZHUtil::sharedInstance()->disableTouchForAllLayers();
}
void GameplayScene::resumeGame()
{
// resume schedule and actions
ZHUtil::sharedInstance()->resumeScheduleAndActionsForAllLayers();
ZHUtil::sharedInstance()->resumeScheduleAndActionsForAllEnemies();
m_kiki->resumeSchedulerAndActions();
// enable touch
ZHUtil::sharedInstance()->enableTouchForAllLayers();
}
As usual, I also set the flag appropriately and then use utility method from ZHUtil class to do things for it. In this case I need to do operations as I noted out in the 2nd comment above.
It may look a little bit confuse to you as I want GameplayScene to control Pause/Resume flow, the logic is inside this class. But the actual touch event comes when we touch pause button lie inside hudcontrol-layer.
HudControl Layer
void HUDControlLayer::_menuPauseCallback(CCObject* pSender)
{
Core::sharedCore()->log("Pause button is clicked.");
// pause the game
ZHUtil::sharedInstance()->getGameplayScene()->pauseGame();
// add pause layer to the root of GameplayScene
PauseLayer* pauseLayer = PauseLayer::create();
ZHUtil::sharedInstance()->getGameplayScene()->getParent()->addChild(pauseLayer, TOPMOST_LAYER, PAUSE_LAYER);
}
When the button is touched, then I pause the game (according to logic) and pop up a pause-layer. Thus pause-layer is responsible for future going back to normal game session.
I involved much of ZHUtil there, but it’s my current code-base and style and also works fine.
Let me know if you have any thought or would like to discuss.
EDIT: I removed out the setting of pause-flag as we don’t really need it because we already pause the schedule so the code won’t come in.