问题描述
我在 cocos2d 游戏的主游戏层/场景中使用半单例方法,如后面的代码所示.
I'm using the semi-singleton approach for the main game layer/scene of my cocos2d game as shown in the later code.
目标是通过调用 [[GameLayer sharedGameLayer] restart] 方法使用暂停或游戏结束层中的按钮正确重新启动/重新创建此单例场景.
The objective is to properly restart/recreate this singleton scene using a button in a pause or gameover layers by calling: [[GameLayer sharedGameLayer] restart] method.
问题是如果我为此使用 CCTransition 效果,并使用 sharedGameLayer = nil; 行覆盖 GameLayer 的 dealloc 方法(到确保静态变量的重置),sharedGameLayer 变量在第一次重启后(也就是第一次 dealloc 后)保持为零,所以调用 restart 方法什么都不做.
The problem is if I use a CCTransition effect for that, and override the GameLayer's dealloc method with sharedGameLayer = nil; line (to ensure the resetting of the static variable), the sharedGameLayer variable stays nil after the first restart (aka. after the first dealloc), so calling the restart method does nothing.
怀疑的方法根本不覆盖 dealloc 方法,而是在使用 replaceScene: 重新启动场景之前,我设置sharedGameLayer 为零.
What works with suspicion is not to override the dealloc method at all, but before restarting the scene using replaceScene:, I set the sharedGameLayer to nil.
问题:这是重新启动/重新创建这个半单例类的正确方法吗?
Question: Is this the right approach for restarting/recreating this semi-singleton class?
提前致谢.
代码:
GameLayer.m:
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;
/