in cocos2d-iphone

Difference between update: and fixedUpdate: in Cocos2D?

update: vs fixedUpdate:

The question about fixedUpdate: in Cocos2D (FixedUpdate in Unity) appears quite regularly on different forums. It was answered many times. However, even after getting the answer some people still have some questions.

The typical answer to this question is that update: is called once per frame and fixedUpdate: is called at constant rate.

I will be writing about update: and fixedUpdate: in Cocos2D-Swift (ex. Cocos2D-iPhone), but same can be said about the Update and FixedUpdate methods in Unity.

But what does that mean? And more importantly, when should you write your code in the update: method and when to use fixedUpdate: in Cocos2D?

The game as a set of frames

Before understanding where should you write the code, lets question ourselves why do we even need to write the code at all?

Sounds like a crazy question. Of course we write the code to move our game objects, update labels, calculate hit points, path finding and so on. But what is the result of the execution of the most of our code?

The result is what you show on the screen. The current frame.

It doesn’t matter what type of game you create, how many layers of abstraction you have in your code or what patterns you use. In the end your game will be simply displayed frame by frame on the player’s device screen.

Of course we get user input, simulate physics and do many other things that player won’t see, but in the end the only thing that matters is what the player sees on the screen. This is the game from the player’s point of view.

Now, let’s get back to our update methods.

The purpose of the update: method

The purpose of the update: method is to give you an opportunity to update your game (all of your game objects, labels and so on), just before they are rendered on the screen.

In other words if you want some game object to be displayed at some position on the screen, you update its position inside the update: method. Then the whole scene is rendered and you can see your sprite or a label right where you put it.

Imagine you are working on a game where the player throws the ball. The ball flight might look like this:

fixedUpdate_1

Everything looks good, the ball was rendered 8 times in 8 different positions while it travels from start to finish. This means that the update: method was called 8 times. It was called once for each ball position shown on the preceeding image.

Now, imagine that the game’s frame rate drops for some reason. You render the ball at its starting position (1), and then the game freezes for the whole 1s interval. So the next time your code is executed is when the ball should already be at position (8).

fixedUpdate_2

Yes, the situation is bad, the player won’t see that smooth movement. However, we can do nothing about it. The player expects the ball to be at position (8) after waiting for 1s, so we should place the ball there.

We won’t discuss how to avoid the situation with dropped frame rate. For this example we just need to accept the fact that this happens sometimes for any game and understand how the code of our game can adapt to this situation.

There is one interesting question. Should we render the ball at positions 2-7?

Or, if I rephrase the question, do we need to execute the code of the update: method to change position of the ball 8 times (so that it was displayed at this position) or only 2 times?

The player won’t see those intermediate frames anyway, because the ball should travel the whole distance. So there is no reason to execute the code of the update: method for positions 2 – 7.

This means, that the first time update: is executed the ball is at position (1) and the second time update: is executed we put the ball straight to position (8).

The purpose of the fixedUpdate: method

Now, imagine that there is a moving platform between the ball’s positions (1) and (8).

fixedUpdate_3

The platform is moving up and down. Sometimes the ball flies without touching it and sometimes it collides with this platform.

fixedUpdate: in Cocos2D

This means that the ball can end up at position (8a) or (8b).

Don’t forget that the game freezes for one second and our code can be executed only two times, at the starting position and at the finish position.

We still don’t need to render all the intermediate positions, because the player won’t see them. But how do we know where we should display the ball, at position (8a) or at position (8b)?

This is where fixedUpdate: comes to the rescue. The fixedUpdate: method will be executed for all those intermediate positions, which we skipped because of low frame rate.

This way, at position (4) we can check if the ball collides with the platform and modify its trajectory.

Of course this will be very basic collision detection, since the ball might not reach the platform at position (4) and already fly through the platform at position (5), but it will do for this example.

How update: and fixedUpdate: are called in reality

So the update: method is called once per frame to give you the chance to update your game objects right before they will be drawn. And the fixedUpdate: method is called at constant rate to give you the chance to react on situations that happen between the frames, even if the frame rate drops.

Here is the situation when the frame rate is high and stable:

fixedUpdate: in Cocos2D

In Cocos2D both update: interval and fixedUpdate: interval are by default set to 1/60th of the second, so in ideal world we would get the situation shown on the preceding image, where update: and fixedUpdate: are executed always at the same time.

However, in the real world, more often you can experience the following situation:

fixedUpdate: in Cocos2D

And sometimes even following:

fixedUpdate_7

How this works

The code that calls both the update: and the fixedUpdate: methods works this way.

Cocos2D gets the time interval(delta) since the last time your game’s code was executed by iOS and checks how many fixedUpdate: method calls should have occurred during this time interval. Then Cocos2D calls the fixedUpdate: method required number of times.

In other words it just breaks time interval into identical chunks and calls the fixedUpdate: method once for each full chunk. This is why the delta parameter passed to fixedUpdate: is always constant and set by the CCSetupFixedUpdateInterval configuration option.

Then, after calling fixedUpdate: required number of times, Cocos2D calls the update: method, but only once.

In this case, the delta parameter of the update: method contains the actual time passed since the last time it was called.

Should I just always use fixedUpdate: ?

After learning about the fixedUpdate: method you can think that you should just always use the fixedUpdate: method. This is not entirely true.

If you’re moving non-physics objects, updating label text or your UI then there is no reason to put this code in fixedUpdate:. Otherwise you might just perform unnecessary work between the frames, by executing this code several times, when it can be executed only once, right before rendering.

However, if you’re detecting collisions, working with physics objects (your own implementation or using physics engine) you should always use fixedUpdate:.

More Information

If you want to learn more about game development with Cocos2D v3 you can read my upcoming book, which will be published in a few days.

Update: Already published.

Also, you can find information about implementing fixed time step in this great article.

Thanks for reading!

Write a Comment

Comment