Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the same time the update(currentTime:) function uses? (before it is called)

Question: The update(currentTime:) function in SKScene is called every frame with a currentTime argument. I'm wondering how to get the time from the same source update(currentTime:) uses without using the update function. I only found CFAbsoluteTimeGetCurrent() which is different.

Reason: To calculate timeSinceLastUpdate you need an instance variable called timeOfLastUpdate. To implement timeOfLastUpdate you need to set it to an arbitrary value before the first update which makes the first calculation of timeSinceLastUpdate incorrect. You could have a simple if statement to detect this or use optionals but that is an unneeded branch which could be avoided if I just set timeOfLastUpdate in didMoveToView(view:). And that is what I'm trying to do.

like image 543
Mazen Avatar asked Jul 06 '16 20:07

Mazen


2 Answers

The first timeSinceLastUpdate will always be different from the rest. Typically one stores the absolute time from the previous update call and subtracts it from the current call's time to get a timeSinceLastUpdate. If the previous time doesn't exist because you're on the first pass through the render loop — it's set to zero or infinity or negative something or whatever sentinel value you initialized it to, just set your timeSinceLastUpdate to some nominal value for getting started. Something like your frame interval (16.67 ms if you're going for 60 fps) would make sense — you don't want game code that depends on that time interval to do something wild because you passed it zero or some wildly huge value.

In fact, it's not a bad idea to have logic for normalizing your timeSinceLastUpdate to something sane in the event that it gets foo large — say, because your user paused and resumed the game. If you have game entities (such as GameplayKit agents) whose movement follows some sort of position += velocity * timeSinceLastUpdate model, you want them to move by one frame's worth of time when you resume from a pause, not take a five-minute pause times velocity and jump to hyperspace.

If you initialize your previous time to zero, subtract, and normalize to your expected frame interval, you'll cover both the starting and unpausing cases with the same code.

like image 137
rickster Avatar answered Oct 12 '22 01:10

rickster


You could always use coalesce:

let deltaTime = currentTime - (previousTime ?? currentTime).  

On first loop, your deltaTime is 0 (Should be this) after that, it is the change

Of course previousTime must be an optional for this to work

like image 30
Knight0fDragon Avatar answered Oct 12 '22 02:10

Knight0fDragon