1
votes

I'm pretty new working with SpriteKit. I have a working example of an game I want to develop. I have some time based movements of sprites, with these I mean:

SKSpriteNode * track = (SKSpriteNode *) node;
CGPoint trackVelocity = CGPointMake(0, -objectVelocity);
CGPoint amtToMove = CGPointMultiplyScalar(trackVelocity,_dt);     
track.position = CGPointAdd(track.position, amtToMove);

where "_dt" is:

-(void)update:(CFTimeInterval)currentTime {
    if (_lastUpdateTime)
    {
        _dt = currentTime - _lastUpdateTime;
    }
    else
    {
        _dt = 0;
    }
    _lastUpdateTime = currentTime;
}

The problem I'm having is that when the user goes to background and comes back to the app a long time later that _dt is HUGE, so all the sprites that are moved with the _dt variable are gone from screen and never come back... I can't find a way of setting this _dt to a correct value.

How can I achieve this?

Thanks a lot!!

I already have in the AppDelegate the following added:

- (void)applicationWillResignActive:(UIApplication *)application
{
    SKView *view = (SKView *)self.window.rootViewController.view;
    view.paused = YES;   
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
   SKView *view = (SKView *)self.window.rootViewController.view;
   view.paused = NO;
}

And it pauses the game, but the _dt that is set in the update is still being changed to a HUGE number and all my sprites go out of screen.

Here is the output of when going to background and coming back: NSLog(@"%f %f",_lastUpdateTime,_dt);

2014-06-30 08:34:00.988 TestingSpriteKit[26303:60b] 224490.130906 0.033162
2014-06-30 08:34:19.761 TestingSpriteKit[26303:60b] 224508.904119 18.773212
2014-06-30 08:34:19.804 TestingSpriteKit[26303:60b] 224508.947477 0.043359
3

3 Answers

1
votes

Without going into too many options, it sounds like you need to set a BOOL and manage your _dt based on it.

so in applicationWillResignActive:(UIApplication *)application set the bool property in the scene to:

theMainScene.appWentIntoBackground = YES;

and then at the beginning of your update method, manage your time interval based on the bool. I don't know whether you want a default amount, or just to skip the entire gap, etc, but something like this maybe:

if (_appWentIntoBackground == YES) {
    _appWentIntoBackground = NO;
    _lastTime = _currentTime;
}
1
votes

You can set a maximum _dt value in your update method such as

if _dt > 1 {
   _dt = 1.0 / 60.0
} 

This is the logic you will see in the Adventure demo app from Apple. Look for kMinTimeInterval to see how they do it.

I think this is a wise solution as there could be additional scenarios, aside from coming back from background, that result in a large delta time.

0
votes

You should pause your SKScene and it's SKView when app goes to background.

When SKView is paused, update: method doesn't get called.