UITapGestureRecognizer从错误的场景调用

时间:2012-02-13 02:48:59

标签: objective-c cocos2d-iphone

如何只能从一个场景访问手势识别器?

我有一个简单的cocos2d应用程序,有两个场景。我在AppDelegate中创建了一个UITapGestureRecognizer:

CCScene *gameScene = [GameLayer scene];
GameLayer *gameLayer = (GameLayer *) [gameScene.children objectAtIndex:0];

// Capture a tap
UITapGestureRecognizer *tapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:gameLayer action:@selector(handleTapFrom:)] autorelease];
[tapRecognizer setDelegate:viewController];
[viewController.view addGestureRecognizer:tapRecognizer];

[[CCDirector sharedDirector] runWithScene:gameScene];

这很有效,我接触了触摸事件,一切都很花花公子。但是,我想切换到我的暂停屏幕的另一个场景,我喜欢这样:

    PauseMenuScene *pauseMenu = [PauseMenuScene node];
    [[CCDirector sharedDirector] replaceScene:pauseMenu];

然而,当该场景启动时,如果我触摸它上面的任何地方就会崩溃。这似乎是因为接触游戏是停滞不前的游戏。

如何防止这种情况?


在安德鲁斯证实了我的怀疑之后,我能够解决这个问题。我仍然无法弄清楚如何将UIGestureRecognizers添加到单个场景中,但我做的是直接将手势发送给我的委托,然后将它们解析到我的场景。这是一个片段:

在AppDelegate中创建手势识别器(更改为指向自己):

UITapGestureRecognizer *tapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapFrom:)] autorelease];
[tapRecognizer setDelegate:viewController];
[viewController.view addGestureRecognizer:tapRecognizer];

接下来,我确定我的主类实际上有一个CCScene类(我刚刚离开基本的HelloWord类,所以它只有一个CCLayer类)。该课程如下:

@implementation GameScene
@synthesize layer = _layer;

-(id) init
{
    if (self = [super init])
    {
        self.layer = [GameLayer node];
        [self addChild:_layer];
    }

    return self;
}

-(void) dealloc
{
    [_layer release];
    _layer = nil;
    [super dealloc];
}

@end

最后,我委托了水龙头:

-(void) handleTapFrom: (UITapGestureRecognizer *) recognizer
{
    CCScene *currentScene = [[CCDirector sharedDirector] runningScene];

    if ([currentScene isKindOfClass:[GameScene class]])
    {
        GameLayer *gLayer = ((GameScene *) currentScene).layer;
        [gLayer handleTapFrom:recognizer];
    }
}

1 个答案:

答案 0 :(得分:1)

您的手势识别器初始化为一个场景的目标,但是当您replaceScene时,该目标不再存在,对吗?因此,您的手势识别器正在尝试将触摸发送到不存在的图层。我怀疑这是你崩溃的原因。

我建议您将触摸控件添加到各个cocos类中,以便每个场景都可以自行处理触摸。当该场景被释放并被另一个场景替换时,它也有自己的触摸识别器。这比向App Delegate添加触摸控件要安全得多,而App Delegate实际上并不是这类场景特定逻辑的地方(通常)。