@andyburke:
The problem I was experiencing was fixed in a patch to trunk some time last fall. I don't remember which release had the fix, but it basically used the changes to RotateTo (now CCRotateTo) that I outlined above.
So, if you're experiencing a similar problem and you're using a newer release of Cocos2d, maybe my patch didn't handle all cases? Not sure.
As far as moving and rotating the ladybug to the touched location, the code is not too complicated. Fair warning, I am a really bad programmer, so check anything I write carefully. Also, I'm pretty sure I borrowed some of this code from elsewhere, and I can't remember where. Anyway, here it is:
- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if( touch ) {
CGPoint location = [touch locationInView: [touch view]];
// The touches are always in "portrait" coordinates. You need to convert them to your current orientation
CGPoint convertedPoint = [[Director sharedDirector] convertCoordinate:location];
// First we stop the all running actions
[ladybug stopAllActions];
// Move at a constant speed to the touched locations
float speed = 200.0;
CGPoint startPosition = [ladybug position];
float newDuration = ccpDistance(startPosition, convertedPoint) / speed;
[ladybug runAction: [MoveTo actionWithDuration:newDuration position:convertedPoint]];
// Rotate to the touched location if distance is greater than 20 pixels
if ( ccpDistance(startPosition, convertedPoint) > 20.0)
{
float opposite = convertedPoint.x - [ladybug position].x;
float adjacent = convertedPoint.y - [ladybug position].y;
float at = (float) CC_RADIANS_TO_DEGREES( atanf( opposite/adjacent) );
if( adjacent < 0 ) {
if( opposite < 0 )
at = 180.0 + abs(at);
else
at = 180.0 - abs(at);
}
NSLog(@"Opposite: %f", opposite);
NSLog(@"Adjacent: %f", adjacent);
NSLog(@"Ladybug roation: %f", [ladybug rotation]);
NSLog(@"AT: %f", at);
[ladybug runAction:[RotateTo actionWithDuration:0.3 angle: at]];
}
// no other handlers will receive this event
return kEventHandled;
}
// we ignore the event. Other receivers will receive this event.
return kEventIgnored;
}
Hope that makes sense. If not, feel free to post follow-up questions.