NMunro
NMunro

Reputation: 1290

Sprite Kit: How to add scene on top of running scene

So I'm working on porting my cocos2d game to Sprite Kit.

In cocos2d I had 2 situations where I would overlay a menu over the entire game scene. The first case is pause, and the second case is game over.

In cocos2d for the game over I did

CCScene *runningScene = [[CCDirector sharedDirector] runningScene];
WaveEndLayer *waveEndedLayer = [[WaveEndLayer alloc] initWithWon:didWin];
[waveEndedLayer setOpacity:0];
[runningScene addChild:waveEndedLayer z:kZHUD];
CCFadeTo *fadeIn = [CCFadeTo actionWithDuration:0.5 opacity:255];
[waveEndedLayer runAction:fadeIn];

The WaveEndLayer class had some CCMenuItems on it, and cocos2d handled passing the touch events to their handlers.

What is the proper way of doing something like this in sprite kit?

What should my game over class inherit from (SKNode, SKView, SKScene)?

I tried using an SKScene, but you can't have 2 running scenes (or am I wrong?), so I was adding the scene as a child to the main game scene. But the touch events were only getting called on the main game scene, not on the game over scene. So I tried something like

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];

    if (_gameOver)
    {
        [_gameOverScene touchAtLocation:location];
    }
}

But for simplicity purposes I'm not resetting the state of everything when I restart a level, I'm just pushing the game scene again, which it didn't like since it was technically still running.

Anyways, whats the proper way of overlaying a menu that needs touch events?

Upvotes: 1

Views: 3187

Answers (1)

NMunro
NMunro

Reputation: 1290

So I ended up using an SKNode for my game over.

I add the layer as a child to my game scene in its init method.

_gameOverLayer = [[GameOverLayer alloc] initWithSize:size];
_gameOverLayer.alpha = 0;
[self addChild:_gameOverLayer];

My game over method looks like this:

- (void)gameOver
{
    _gameOver = YES;
    SKAction *fade = [SKAction fadeInWithDuration:0.5];
    [_gameOverLayer runAction:fade];
}

And then I changed my touch method on my game scene to have this:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];

    if (_gameOver)
    {
        [_gameOverLayer touchesEnded:touches withEvent:event];
        return;
    }
    ...
}

Everything works perfectly, the game over appears on top of the running game, and can get input.

Upvotes: 4

Related Questions