Gesture recogniser crashing upon next level

191 views Asked by At

I am trying to implement a gesture recogniser and everything is working well until it comes to loading the next level, then at the next level stage, where can tap to go to the next level, if I use a gesture, the program crashes.

To be clear, when a level is complete a title appears saying "Next Level - touch to go to next level". Until I added the gesture recogniser a tap would result in incrementing the level and presenting the same scene using [super initWithSize:size] with new variables based on the level number. When I added the gesture recogniser, when "Next Level - touch to go to next level" is on screen, a tap will still take me to the next level but a pan crashes the app.

My gesture recogniser is below.

- (void)didMoveToView:(SKView*)view {

    UIGestureRecognizer *spinner = [[UIPanGestureRecognizer alloc] initWithTarget:self     action:@selector(handlePanGesture:)];
    [self.view addGestureRecognizer:spinner];

}



- (void)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer {

    CGPoint velocity = [gestureRecognizer velocityInView:self.view];

    if (velocity.y > 0) {

            NSLog(@"gesture went down");

    } else {

            NSLog(@"gesture went up");

    }
}

The problem may be in the way I am incrementing levels or implementing touch so here is the touches began method and the level increment code

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    BOMPlayerNode *playerNode = (BOMPlayerNode*)[self childNodeWithName:@"Player"];

    if (!self.restart) {

        for (UITouch *touch in touches) {
    CGPoint positionInScene = [touch locationInNode:self];

    int duration = 1.0;

    SKAction * actionMove = [SKAction moveTo:CGPointMake(positionInScene.x, positionInScene.y) duration:duration];
    [playerNode runAction:actionMove];

        }
    } else if ( self.restart && self.nextLevel ) {
        levelCount++;
        for (SKNode *node in [self children]) {
            [node removeFromParent];
        }


        BOMGamePlayScene *scene = [BOMGamePlayScene sceneWithSize:self.view.bounds.size];
        [self.view presentScene:scene];

    } else if ( self.restart && self.tryAgain ) {
        for (SKNode *node in [self children]) {
            [node removeFromParent];
        }


        BOMGamePlayScene *scene = [BOMGamePlayScene sceneWithSize:self.view.bounds.size];
        [self.view presentScene:scene];
    }

}

- (void) update:(NSTimeInterval)currentTime {

    if (GameOverConditions) {

        self.tryAgain = YES;
        self.restart = YES;
        [self performGameOver];

    } else if (NextLevelConditions) {

        self.restart = YES;
        self.nextLevel = YES;
        [self performNextLevel];

    }

}


- (void) performGameOver {
    if (!self.gameOverDisplayed) {
        BOMGameOverNode *gameOver = [BOMGameOverNode gameOverAtPosition:CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))];
        self.gameOverDisplayed = YES;
    }

}

- (void) performNextLevel {
    if (!self.nextLevelDisplayed) {
        BOMNextLevelNode *nextLevel = [BOMNextLevelNode     nextLevelAtPosition:CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))];
        self.nextLevelDisplayed = YES;
    }

}

Any help would be much appreciated.

1

There are 1 answers

1
0x141E On BEST ANSWER

Gesture recognizers aren't automatically removed from the SKView when you transition to a new scene. You will need to remove them manually. Your pan gesture recognizer is configured to call [self handlePanGesture];. However, self was released when you transitioned to the new scene. When you attempt to pan in the new scene, the old, released recognizer handler is called, causing the crash. To remedy this, you will need to remove the recognizers from the view. Here's an example of how to do that:

// Add this to your SKScene subclass. It will automatically be called when you
// transition to a new scene.
- (void) willMoveFromView:(SKView *)view {
    // Remove all gesture recognizers from the view
    for (UIGestureRecognizer *gesture in view.gestureRecognizers) {
        [view removeGestureRecognizer:gesture];
    }
}