Like in any game engine there are 2 different methods to draw and update things.
Each node has a draw method. This method is called every frame.
The purpose of this method is to draw and only draw the node, nothing more, nothing less.
You should not update ivars in this method.
CCNode has an empty draw method.
// This is CCNode's draw method -(void) draw { // override me // Only use this function to draw your stuff. // DON'T draw your stuff outside this method }
So, if you want to have a custom node, probably you will also need to override the draw method.
It is worth noting that the following OpenGL states are preset before calling draw:
IMPORTANT: If you need to enable/disable any of these states (or any other), you need to restore when you finish using them. Example:
// example of custom draw -(void) draw { // In this example the color array is not needed, so it needs to be disabled, since it is enabled by default. // Disable color array glDisableClientState(GL_COLOR_ARRAY); // draw your stuff // restore the color array state glEnableClientState(GL_COLOR_ARRAY); }
Each node, by default, has no updates. If you want to update the state of your node you should schedule a callback
The recommended way to do it is by calling CCNode scheduling methods, and not by using NSTimer.
CCNode has the following method to timer
Properties of these method:
scheduleUpdate and/or scheduleUpdateWithPriority are the recommended way to schedule a callback (available since v0.99.3).
If they are called, the update method will be called every frame with the “delta time” as argument.
scheduleUpdate is the same as: scheduleUpdateWithPriority:0
Example:
// My custom node -(id) init { // -10 means that the update method of this node will be called before other update methods which priority number is higher [self scheduleUpdateWithPriority:-10]; } -(void) update:(ccTime)deltaTime { // update your node here // DON'T draw it, JUST update it. // example: rotation_ = value * deltaTime; }
Try to use scheduleUpdate over scheduleSelector since it is a little bit faster and consumes a little less memory.
To unschedule the update method, you should use:
[node unscheduleUpdate];
scheduleSelector:(SEL)selector interval:(float)interval is the “old” way of scheduling callbacks.
You can schedule callbacks with an interval, but without priority.
If you use interval==0 or you don't use an interval, then the schedule callback will be called every frame.
Example:
-(id) init { // the "step:" selector will be called every 0.5 seconds [self schedule:@selector(step:) interval:0.5f] } -(void) step:(ccTime) deltaTime { // update your stuff here }
To unschedule a callback you should call:
[node unscheduleSelector:@selector(step:)];