Thursday, December 4, 2008

cocos2d: propagating touch events

cocos2d v0.6 has a new way to propagate and most importantly, to stop the propagation of touch events.

The old interface was using the UIKit interface:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
The new interface is very similar, but instead of returning void, it now returns a BOOL, and since the return value can't be used as part of the selector's identity, the selector was renamed. The prefix 'cc' (short of cocos2d) was prepended. Example:
- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (BOOL)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (BOOL)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
If a certain layer handles the event then it should return kEventHandled, else it should return kEventIgnored.

Example taken from Menu.c:
- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView: [touch view]];
int idx;

MenuItem *item = [self itemInPoint: point idx:&idx];

if( item ) {
[item selected];
selectedItem = idx;

// Event handled. It won't be propagated
return kEventHandled;
}

// event not handled. It will be propagated to the next
// Layer on the stack
return kEventIgnored;
}

Which Layer is the first one to receive the event ?
The last Layer to be added. If this layer doesn't return kEventHandled, then the event will be propagated to the next Layer on the stack.

No comments: