後のコードに示すように、cocos2d ゲームのメイン ゲーム レイヤー/シーンにセミ シングルトン アプローチを使用しています。
目的は、 [[GameLayer sharedGameLayer] restart]メソッドを呼び出して、一時停止レイヤーまたはゲームオーバー レイヤーのボタンを使用して、このシングルトン シーンを適切に再起動/再作成することです。
問題は、そのために CCTransition 効果を使用し、GameLayer のdeallocメソッドをsharedGameLayer = nil;でオーバーライドする場合です。行 (静的変数のリセットを確実にするため) では、sharedGameLayer 変数は最初の再起動後 (別名、最初の dealloc 後) に nil のままであるため、restartメソッドを呼び出しても何も起こりません。
疑いを持って動作するのは、 deallocメソッドをまったくオーバーライドしないことですが、replaceScene:を使用してシーンを再起動する前に、sharedGameLayer を nil に設定します。
質問:これは、このセミシングルトン クラスを再起動/再作成するための正しいアプローチですか?
前もって感謝します。
コード:
GameLayer.m:
static GameLayer *sharedGameLayer;
@implementation GameLayer
- (id)init
{
NSLog(@"%s", __PRETTY_FUNCTION__);
// 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])
{
// Set the sharedGameLayer instance to self.
sharedGameLayer = self;
// Set the initial game state.
self.gameState = kGameStateRunning;
// Register with the notification center in order to pause the game when game resigns the active state.
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(pauseGame) name:UIApplicationWillResignActiveNotification object:nil];
// Enable touches and multi-touch.
CCDirector *director = [CCDirector sharedDirector];
[director.touchDispatcher addTargetedDelegate:self priority:0 swallowsTouches:YES];
director.view.multipleTouchEnabled = YES;
// Set the initial score.
self.score = 5;
// Create the spiders batch node.
[self createSpidersBatchNode];
// Load the game assets.
[self loadAssets];
// Play Background music.
if (![SimpleAudioEngine sharedEngine].isBackgroundMusicPlaying)
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"backgroundmusic.mp3" loop:YES];
// Preload sound effects.
[[SimpleAudioEngine sharedEngine] preloadEffect:@"inbucket.mp3"];
[[SimpleAudioEngine sharedEngine] preloadEffect:@"outbucket.mp3"];
[[SimpleAudioEngine sharedEngine] preloadEffect:@"gameover.mp3"];
// Schdule updates.
[self scheduleUpdate];
[self schedule:@selector(releaseSpiders) interval:0.7];
}
return self;
}
- (void)createSpidersBatchNode
{
NSLog(@"%s", __PRETTY_FUNCTION__);
// BatchNode. (For Animation Optimization)
self.spidersBatchNode = [CCSpriteBatchNode batchNodeWithFile:@"spiderAtlas.png"];
// Spider sprite + BatchNode + animation action.
for (int i = 0; i < 50; i++) {
Spider *spider = [[Spider alloc] init];
spider.spiderSprite.visible = NO;
}
[self addChild:self.spidersBatchNode];
}
- (void)restartGame
{
// Play button pressed sound effect.
[[SimpleAudioEngine sharedEngine] playEffect:@"button.mp3"];
// Nil'ing the static variable.
sharedGameLayer = nil;
// Restart game.
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[GameLayer scene]]];
}
+ (CCScene *)scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// Game Layer.
// 'gameLayer' is an autorelease object.
GameLayer *gameLayer = [GameLayer node];
// add gameLayer as a child to scene
[scene addChild: gameLayer];
// HUD Layer.
HUDLayer *hudLayer = [HUDLayer node];
[scene addChild:hudLayer];
gameLayer.hud = hudLayer;
// return the scene
return scene;
}
+ (GameLayer *)sharedGameLayer
{
return sharedGameLayer;
}
- (void)cleanup
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[CCDirector sharedDirector].touchDispatcher removeDelegate:self];
[self stopAllActions];
[self unscheduleAllSelectors];
[self unscheduleUpdate];
[self removeAllChildrenWithCleanup:YES];
self.hud = nil;
[super cleanup];
}
//- (void)dealloc
//{
// sharedGameLayer = nil;
//}
@end