My last post I mused over how I could handle the connect yet unconnected nature of using SpriteKit and how I was doing spawning and timing in my game. I am please the say that the solution was far more simpler then I was dreaming of.
To recap, my game run off the time it gets from the SKScene.update method. I would then calculate how much time has past between the frames and then pass the “delta” to all my other objects that needed updating.
After some searching I decided to treat my game logic more like how I would a physic engine. Instead of passing in the delta time between each frame. I now process a fixed amount of time, multiple times during each frame. Keep reading if that doesn’t make sense, hopefully I can explain this more clearly.
Currently SpriteKit calls the frame update method about every 0.016 seconds. I decided that I would set my step time to 0.014 seconds. Or in other words my game logic would calculate how much has changed in 0.014 seconds. It would does this calculation at least once every 0.016 seconds.
One problem with this is that if my game logic updates every 0.014 seconds and SpriteKit updates about every 0.016 seconds, after 7 frames update my game logic would be one frame behind (0.016 * 7 = 0.112; 0.014 * 7 = 0.098; 0.112 – 0.098 = 0.014). It doesn’t seem like a lot, but after a few seconds everything in the game would be wrong and no one would want to play it.
To fix this problem of missing steps, I keep a sum of the delta time between each frame in a variable called “simulationTime”. Then if simulationTime is greater then 0.014 I take a step. After each step I subtract 0.014 from simulationTime. I continue doing this until simulationTime is less then 0.014. Using the numbers above, every 7 frame updates I would take an extra step.
Now to have the game logic move faster or slower, it is just a matter of multiplying the delta time between frames by the speed the user selected. If the player wants the game to run 2x faster, I just times the frame delta by 2 and my game will take the correct number of steps each frame. If I want it to move half the normal speed then I just times it by 0.5 and it just works.
I am really happy to see is that even if the game is running 2x times faster (it is taking 3 to 4 steps each frame) the game is still running around 60 FPS without any problems. If I start having issues with a drop in FPS I can always raise or lower the step interval, but I wont worry about that unless I need too.
Overall I am pleased with this. I can now continue using SpriteKit and enjoy the animation, and still have the rest of my game run smoothly with no issues. I am hoping that I can convert a more of my code to SpriteKit and reduce the number of lines that I have written.
One thing that I did notice during this time, is that I can no longer use the simulator; I have to use my device. When testing in the simulator the game is running at about 12 to 20 FPS. While on my device I get about 60 FPS. I also notice strange slow downs on the simulator, but not on the device.
If you want to learn more about variable time stepping a great resource is this blog post.