나는 잠시 조용하게이 문제를 진단하려고 진짜 두통을 느낀다.다른 레이어에서 게임/장면 다시 시작
세부 사항 :
I 다음 노드가 있습니다
- GameLayer를; 메인 게임 층, 또한 세미 싱글 톤.
- HUDLayer; 물론 GameLayer와 함께 장면에 추가 된 간단한 HUD 레이어 (점수 및 일시 중지 버튼 용).
- PauseLayer; 간단한 메뉴 (resume, restart, main menu)를 가지고있는 CCLayerColor 서브 클래스.
일시 중지 버튼을 누를 때마다 PauseLayer가 자식으로 GameLayer에 추가됩니다.
문제 : GameLayer 자체 내에서 [자기 restartGame] : 게임/장면을 다시 시작
에 의해 잘 작동합니다. 그러나 다음과 같이 PauseLayer에서 같은 메서드를 호출합니다. [[GameLayer sharedGameLayer] restartGame]은 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;
}
EDIT : GameLayer의 init 메소드에서 Pause 레이어 (GameLayer의 자식으로, 항상 표시됨)를 추가하면 모든 것이 완벽하게 작동합니다 .. 조금 이상합니다.
모든 입력 사항을 높이 평가합니다. 미리 감사드립니다. 당신은 그것을 클래스 멤버 변수 있지 않은지 확인하기 위해 @implementation 클래스 줄 앞에 줄을 쓰기 위해 필요한 라인
static GameLayer *sharedGameLayer;
에서
새 질문의 URL은 다음과 같습니다. [link] (http://stackoverflow.com/questions/17395827/properly-restarting-re-initializing-a-semi-singleton) – MHany