我现在正试图将这个问题暂时解决这个问题让我很头疼。
详细信息:
我有以下节点:
只要按下暂停按钮,PauseLayer就会作为孩子添加到GameLayer中。
的问题:
通过以下方式重新启动游戏/场景: [self restartGame] 来自GameLayer本身。
但是使用: [[GameLayer sharedGameLayer] restartGame] 从PauseLayer调用相同的方法并不能完全用新实例替换GameLayer场景;尽管GameLayer的dealloc被调用(仅当没有使用过渡时),旧场景仍然没有孩子,同样的旧分数等。
代码:
GameLayer
static GameLayer *sharedGameLayer;
@implementation GameLayer
- (id)init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if(self = [super initWithColor:ccc4(255, 255, 255, 255) width:[CCDirector sharedDirector].winSize.width height:[CCDirector sharedDirector].winSize.height])
{
NSLog(@"%s", __PRETTY_FUNCTION__);
sharedGameLayer = self;
.
.
}
+ (GameLayer *)sharedGameLayer {
@synchronized(self) {
if (sharedGameLayer == nil) {
sharedGameLayer = [[self alloc] init];
}
}
return sharedGameLayer;
}
- (void)pauseGame
{
NSLog(@"%s", __PRETTY_FUNCTION__);
if (![[CCDirector sharedDirector] isPaused])
{
// Disable the top menu.
self.hud.topMenu.enabled = NO;
// Pause game.
[[CCDirector sharedDirector] pause];
// Pause the background music.
[[SimpleAudioEngine sharedEngine] pauseBackgroundMusic];
// Disable touch detection.
[[CCDirector sharedDirector].touchDispatcher removeDelegate:self];
// Add the Pause Layer.
PauseLayer *pauseLayer = [[PauseLayer alloc] init];
pauseLayer.tag = 2;
pauseLayer.zOrder = 10;
[self addChild:pauseLayer z:10 tag:2];
}
}
- (void)restartGame
{
NSLog(@"%s", __PRETTY_FUNCTION__);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[CCDirector sharedDirector].touchDispatcher removeAllDelegates];
[self stopAllActions];
[self unscheduleAllSelectors];
[self unscheduleUpdate];
[self removeAllChildrenWithCleanup:YES];
[[CCDirector sharedDirector] replaceScene:[GameLayer scene]];
//[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[GameLayer scene]]];
}
- (void)dealloc
{
NSLog(@"%s", __PRETTY_FUNCTION__);
sharedGameLayer = nil;
}
@end
PauseLayer
- (id)init
{
if (self = [super initWithColor:ccc4(0, 0, 0, 128) width:[CCDirector sharedDirector].winSize.width height:[CCDirector sharedDirector].winSize.height])
{
// Create a menu.
// Resume button.
CCLabelTTF *resumeLabel = [CCLabelTTF labelWithString:@"Resume" fontName:@"Marker Felt" fontSize:32];
resumeLabel.color = ccc3(240, 240, 240);
CCMenuItemLabel *resumeButton = [CCMenuItemLabel itemWithLabel:resumeLabel block:^(id sender) {
[[GameLayer sharedGameLayer] resumeGame];
}];
// Restart Game button.
CCLabelTTF *restartLabel = [CCLabelTTF labelWithString:@"Restart" fontName:@"Marker Felt" fontSize:32];
restartLabel.color = ccc3(240, 240, 240);
CCMenuItemLabel *restartButton = [CCMenuItemLabel itemWithLabel:restartLabel block:^(id sender) {
[[GameLayer sharedGameLayer] restartGame];
}];
// Main Menu button.
CCLabelTTF *mainMenuLabel = [CCLabelTTF labelWithString:@"Main Menu" fontName:@"Marker Felt" fontSize:32];
mainMenuLabel.color = ccc3(240, 240, 240);
CCMenuItemLabel *mainMenuButton = [CCMenuItemLabel itemWithLabel:mainMenuLabel block:^(id sender) {
[[GameLayer sharedGameLayer] gotoMainMenu];
}];
CCMenu *menu = [CCMenu menuWithItems:resumeButton, restartButton, mainMenuButton, nil];
[menu alignItemsVerticallyWithPadding:10.0];
menu.position = ccp([CCDirector sharedDirector].winSize.width / 2, [CCDirector sharedDirector].winSize.height / 2);
[self addChild:menu];
}
return self;
}
编辑:
如果我在GameLayer的init方法中添加Pause图层(作为GameLayer的子图层,并且始终可见),一切都很完美..这有点奇怪。
任何输入都非常感谢。
提前谢谢!
答案 0 :(得分:0)
来自
行static GameLayer *sharedGameLayer;
您需要在@implementation类行之前编写此行,以使其不是类成员变量。在sharedGameLayer方法中,您应该将其更改为
+ (GameLayer *)sharedGameLayer {
@synchronized(self) {
if (sharedGameLayer == nil) {
sharedGameLayer = [[self alloc] init];
}
}
return sharedGameLayer;
}
而且,当你定义游戏图层类时,你不会调用init方法,但你应该调用sharedGameLayer来使游戏图层类成为单例。
答案 1 :(得分:0)
我不建议在CCLayers上使用单例模式,但是你是否覆盖/编辑CCScene包装器,因此它不会调用init。
例如
+(id)scene
{
CCScene* scene = [CCScene node];
[scene addChild:[GameLayer sharedGameLayer]];
return scene;
}
然后当你打电话
[[CCDirector sharedDirector] replaceScene:[GameLayer scene]];
请记得在
后立即重启游戏[[GameLayer sharedInstance] restart];
或者你可以在场景包装方法中做到这一点。
希望我明白你的意思。
Atleast这将使你无法一直为游戏层重新分配空间......
答案 2 :(得分:0)
问题的罪魁祸首是在使用CCDirector的 Pause 方法暂停游戏后调用CCDirector的 ReplaceScene:方法。
我做了什么正在实现我自己的“暂停”功能主要使用: [self pauseSchedulerAndActions]; 以及我的情况: [[self.spidersBatchNode children] makeObjectsPerformSelector:@selector(pauseSchedulerAndActions)]; for spriteBatchNode里面的所有孩子。
出现了另一个问题,我将提出另一个问题。
感谢所有回复。