Cocos2d Tip #2: Using CCTimer in Your iPhone Game

If you’re writing almost any type of game, from a puzzler to a FPS to an RTS, tracking time is critical element of the game play. (Except for Angry Birds. You can ponder an Angry Birds level until your iPhone battery runs dry without penalty.)

Cocos2d-iPhone provides several means for tracking time in your game and scheduling methods to be called at both regular heartbeats and at arbitrary points in the future. The easiest way to manage time in a Cocos2d-based game is to use a CCLayer’s scheduleUpdate or schedule methods. Both methods are explained nicely in the timers section of the Cococ2d Best Practices guide. The guide also explains why you should try to avoid using iOS’s NSTimer class. (Your game will miss out on automatic pause and resume if do use NSTimer.)

But what if you can’t use scheduleUpdate or schedule in your game because you’re putting your game logic into a custom class instead of a CCLayer or CCSprite?

For the sake of simplicity and portability I don’t subclass CCSprite in my games. Instead, I create custom classes to represent my game objects and call update:(ccTime)delta on them from CCLayer objects to make stuff happen. I needed a nice timer class and started to write my own. About halfway though this project I ran into Cocos2d’s CCTimer. Since I’m trying to write as little code as possible I abandoned my timer. CCTimer is a nicely written, lightweight timer class that uses NSInvoker to create callbacks and still integrates will with the rest of the Cocos2d-iPhone framework.

Here’s how it use it…

First, I store a reference to a timer in my non-Cocos2d class:

Second, I define a call back method to stop the timer:

Third, I define a method to start the timer:

Fourth, I add a call to update the timer in my CCLayer’s update method:

Finally, Somewhere deep in my game logic I start the timer at the right dramatic moment.

It’s important to note that at the time of this blogging, the CCTimer documentation claims the interval value used to determine the length is in seconds, but really it’s in milliseconds (that is 1/60 of a second). If want your timer’s call back to run in 2 minutes set the CCTimer interval to 160.0f.

It’s also important to note that CCTimer is independent of frame rate: This might be obvious but sometime you want to execute an action every frame an sometime you want to execute it every few milliseconds.

If things aren’t working make sure you’ve told your layer to schedule updates in it’s init method and make sure you are updating your timers from your layer 🙂