首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从另一层重新启动游戏/场景

从另一层重新启动游戏/场景
EN

Stack Overflow用户
提问于 2013-06-28 01:26:08
回答 3查看 358关注 0票数 0

我现在很头疼,想安静地诊断这个问题。

详细信息:

我有以下节点:

  1. GameLayer;主游戏层,也是半单点的.
  2. HUDLayer;一个简单的HUD层(用于得分和暂停按钮),当然与GameLayer一起添加到场景中。
  3. PauseLayer;一个包含简单菜单(恢复、重新启动和主菜单)的CCLayerColor子类。

只要按下暂停按钮,PauseLayer就会作为子级添加到GameLayer中。

问题:

重新启动游戏/场景可以通过: self restartGame从GameLayer本身开始工作。但是,通过使用:[ PauseLayer sharedGameLayer restartGame]调用相同的方法并不能用新实例完全替换GameLayer场景;旧场景仍然存在,没有子场景、老分数等等,尽管GameLayer的dealloc被调用了(只有在不使用转换的情况下)。

代码:

GameLayer

代码语言:javascript
复制
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

代码语言:javascript
复制
- (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方法中添加暂停层(作为GameLayer的子层,并且总是可见的),一切都工作得很完美。这有点奇怪。

任何输入都是非常感谢的。提前感谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-30 22:52:46

这个问题的罪魁祸首是在暂停游戏后调用CCDirector的ReplaceScene:方法,使用CCDirector的暂停方法。

我所做的是实现我自己的“暂停”功能,主要使用: self pauseSchedulerAndActions;在我的示例中还使用:[self.spidersBatchNode子类pauseSchedulerAndActions用于spriteBatchNode中的所有子级。

另一个问题,我将提出另一个问题。

谢谢你的回复。

票数 0
EN

Stack Overflow用户

发布于 2013-06-28 02:54:27

从线上

代码语言:javascript
复制
static GameLayer *sharedGameLayer;

您需要在@implementation行之前编写这一行,以使它不是类成员变量。在sharedGameLayer方法中,您应该将其更改为

代码语言:javascript
复制
+ (GameLayer *)sharedGameLayer {
    @synchronized(self) {
        if (sharedGameLayer == nil) {
            sharedGameLayer = [[self alloc] init];
        }
    }

    return sharedGameLayer;
}

而且,在定义游戏层类时,不需要调用init方法,而是应该调用sharedGameLayer使游戏层类成为单例类。

票数 0
EN

Stack Overflow用户

发布于 2013-06-30 08:52:49

我不建议在CCLayers上使用单例模式,但是是否覆盖/编辑了CCScene包装器,使其不调用init。

例如

代码语言:javascript
复制
+(id)scene
{
    CCScene* scene = [CCScene node];
    [scene addChild:[GameLayer sharedGameLayer]];
    return scene;
}

然后当你打电话

代码语言:javascript
复制
[[CCDirector sharedDirector] replaceScene:[GameLayer scene]];

记得在游戏结束后立即重新开始游戏。

代码语言:javascript
复制
[[GameLayer sharedInstance] restart];

或者你可以在场景包装方法中这样做。

希望我明白你的意思。

至少这能帮你从游戏层重新分配空间,呵呵。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17355853

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档