I basically extend atlasSprite class to my own and add the touchdispatcher stuff there.
I found using a touch radius detection was very fast.
I then moved it to another class I call GridPoints.
Since my sprites jump around from point to point, in my game this made it easier.
You need these things for your own TouchableThing class:
//Need to adhere to this protocol
@interface GridPoint : CocosNode <TargetedTouchDelegate>
//I use touch radius to "test" the touch area - property
CGFloat touchRadius;
//An on off flag is useful to speed up touch dispatcher processing, but keep it in the dispatcher list
BOOL allowTouches;
//Then do this stuff in the class implementation
- (void)onEnter
{ //NSLog(@"inner onEnter ...");
if(self.touchRadius > 0.0f){
[[TouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
[super onEnter];
}
- (void)onExit
{
if(self.touchRadius > 0.0f){
[[TouchDispatcher sharedDispatcher] removeDelegate:self];
}
[super onExit];
}
//The touch calls
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
//if (self.SpawnPoint) return NO;
CGPoint touchPoint = [touch locationInView:[touch view]];
touchPoint = [[Director sharedDirector] convertToGL:touchPoint];
//NSLog(@"inner grid ccTouchBegan ...");
//NSLog(@"touchpoint.position:%f , %f", touchPoint.x, touchPoint.y);
//return NO;
if ([self containsTouchLocation:touchPoint]) {
// code here is only executed if obj has been touched
//NSLog(@" I GOT TOUCHED on the sprite");
originalTouchPoint.x = touchPoint.x;
originalTouchPoint.y = touchPoint.y;
//NSLog(@" originalPoint x:%f, y:%f", originalPoint.x, originalPoint.y);
return YES;
}
return NO;
}
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
// If it weren't for the TouchDispatcher, you would need to keep a reference
// to the touch from touchBegan and check that the current touch is the same
// as that one.
// Actually, it would be even more complicated since in the Cocos dispatcher
// you get NSSets instead of 1 UITouch, so you'd need to loop through the set
// in each touchXXX method.
// NSLog(@"inner sprite ccTouchEnded ...");
//Use for move stuff
}
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchPoint = [touch locationInView:[touch view]];
touchPoint = [[Director sharedDirector] convertToGL:touchPoint];
int direction = 0;
//angle: Actually it's ATan2(dy , dx) where dy = y2 - y1 and dx = x2 - x1, or ATan(dy / dx)
float degrees = CC_RADIANS_TO_DEGREES(atan2(touchPoint.x - originalTouchPoint.x, touchPoint.y - originalTouchPoint.y));
//NSLog(@"RUNICA OUT: ANGLE:%f", CC_RADIANS_TO_DEGREES(atan2(touchPoint.x - originalTouchPoint.x, touchPoint.y - originalTouchPoint.y)));
//that is gving me 0-180 and the negative 0-180
//I was using this to detect angles.
//DO stuff here
if (self.ownerlayer != nil) {
//I call back to my game layer by having a circular reference
[self.ownerlayer MoveMeCallout:direction thisGridPoint:self];
}
// NSLog(@"self.position:%f , %f", touchPoint.x, touchPoint.y);
}
- (BOOL)containsTouchLocation:(CGPoint)touch
{
//NSLog(@"containsTouchLocation .checking ......");
//return CGRectContainsPoint(self.rect, [self convertTouchToNodeSpaceAR:touch]);
//use radius based
CGFloat distance = ccpDistance(self.mypos, touch);
//NSLog(@"containsTouchLocation .checking ....distance: %f", distance);
//NSLog(@"containsTouchLocation .checking ....in touchRadius: %f", self.touchRadius);
return (distance <= self.touchRadius);
}