schirrmacher
schirrmacher

Reputation: 2357

Consistent Rotation Speed, iOS Sprite Kit

I'd like to rotate a spaceship around the z axis with the SKAction rotation method, depending on touch coordinates. After a touch the spaceship's nose should point to the touch point.

CGFloat rad = atan2f(touchPos.y - sprite.position.y, touchPos.x - sprite.position.x); // calc rad between vectors

SKAction *rotation = [SKAction rotateToAngle: rad duration: ??? shortestUnitArc:YES];

How can I adjust the duration so that the rotation speed is always the same (no matter how big the rotation angle is)?

The problem is that the radian occurs in the interval from -pi to pi (because of atan2). So the rotation depends on the quadrant touched and so does the speed.

enter image description here

Upvotes: 1

Views: 615

Answers (2)

schirrmacher
schirrmacher

Reputation: 2357

I got it now:

I've translated the radian from [-Pi, Pi] to [0, 2Pi].

CGFloat prevRad = sprite.zRotation; // actual sprite rotation
if (prevRad < 0) prevRad = (M_PI)+((M_PI)+prevRad); // atan2 from 0 to 2PI

CGFloat rad = atan2f(touchLocation.y - sprite.position.y, touchLocation.x - sprite.position.x); // calc rad between vectors
if (rad < 0) rad = (M_PI)+((M_PI)+rad); // atan2 from 0 to 2PI

Then I used the difference between the old and the new radian divided by a factor:

CGFloat factor = 4.0f;
CGFloat diff = ABS(sprite.zRotation - rad);
CGFloat time = diff / factor;

SKAction *rotation = [SKAction rotateToAngle:rad duration: time shortestUnitArc:YES];
rotation.timingMode = SKActionTimingEaseInEaseOut;
[sprite runAction:rotation];

Upvotes: 2

ZeMoon
ZeMoon

Reputation: 20274

CGFloat factor = 5.0; //Adjust this to get your desired speed.

CGFloat rad = atan2f(touchPos.y - sprite.position.y, touchPos.x - sprite.position.x); // calc rad between vectors

CGFloat diff = ABS(node.zRotation - rad);

CGFloat time = diff / factor;

SKAction *rotation = [SKAction rotateToAngle: rad duration: time shortestUnitArc:YES];

Upvotes: 1

Related Questions