user339946
user339946

Reputation: 6119

Rotate sprite to face a point (cocos2d)

I seem to be having an issue with calculating the angle between my sprite and a touch point. I'm trying to get my sprite to directly face the direction of the touch point whenever the user touches the screen. Here's my code:

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    CGPoint tapPosition;
    for (UITouch *touch in touches){
        CGPoint location = [touch locationInView:[touch view]];
        tapPosition = [self convertToNodeSpace:[[CCDirector sharedDirector] convertToGL:location]];
    }

    float angle = CC_RADIANS_TO_DEGREES(ccpAngle(fish.position, tapPosition));
    [fish runAction:[CCRotateTo actionWithDuration:0.5 angle:angle]];
}

Any ideas? Thanks

Upvotes: 2

Views: 4015

Answers (3)

Barry Wyckoff
Barry Wyckoff

Reputation: 614

Add this to the end of Nikhil's answer to avoid getting a negative angle when the touch location is to the bottom right of the sprite.

if (calculatedAngle < 0) 
{
     calculatedAngle+=360;
}

Upvotes: 4

Nikhil Aneja
Nikhil Aneja

Reputation: 1259

CCPoint pos1 = [fish position]; CCPoint pos2 = touchlocation;

float theta = atan((pos1.y-pos2.y)/(pos1.x-pos2.x)) * 180 * 7 /22;

float calculatedAngle;

if(pos1.y - pos2.y > 0)
{
    if(pos1.x - pos2.x < 0)
    {
        calculatedAngle = (-90-theta);
    }
    else if(pos1.x - pos2.x > 0)
    {
       calculatedAngle = (90-theta);
    }       
}
else if(pos1.y - pos2.y < 0)
{
    if(pos1.x - pos2.x < 0)
    {
       calculatedAngle = (270-theta);
    }
    else if(pos1.x - pos2.x > 0)
    {
       calculatedAngle = (90-theta);
    }
}

Use this calculatedAngle in your Run Action.. hope this helps... :)

Upvotes: 3

Ben Trengrove
Ben Trengrove

Reputation: 8729

Try this out, first of all you don't need that for loop because you are just going to end up with the last touch location anyway. You may as well use [touches anyObject] as below.

Second, I am not sure what ccpAngle does off the top of my head but when macros like that don't work sometimes its easier to just do the maths yourself.

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   CGPoint tapPosition;
   UITouch *touch = [touches anyObject];

   CGPoint location = [touch locationInView:[touch view]];
   tapPosition = [self convertToNodeSpace:[[CCDirector sharedDirector] convertToGL:location]];

   float dY = fish.position.y - tapPosition.y;
   float dX = fish.position.x - tapPosition.x;
   float offset = dX<0 ? 90.0f : -90.0f;
   float angle = CC_RADIANS_TO_DEGREES(atan2f(dY, dX)) + offset;

   [fish runAction:[CCRotateTo actionWithDuration:0.5 angle:angle]];
}

You probably could replace dX and dY with a point from ccpDiff as well but it doesn't really matter. Also depending on where the head of your fish is you may need to adjust the angle offset but I will leave that up to you.

Let me know if this helps.

Upvotes: 3

Related Questions