cocos2dbeginner
cocos2dbeginner

Reputation: 2207

Trying to rotate my sprite smoothly at a constant speed. But it decreases the speed

(I'm using cocos2d for iphone)

First I'll explain you my code: (the important parts)

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

    UITouch * touch = [touches anyObject];

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

    float dstAngle = CC_RADIANS_TO_DEGREES(-ccpToAngle(ccpSub(location, plane.position)));

    plane.dstAngle = dstAngle;
     }
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch * touch = [touches anyObject];

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

    float dstAngle = CC_RADIANS_TO_DEGREES(-ccpToAngle(ccpSub(location, plane.position)));

    plane.dstAngle = dstAngle; }

If I touch the screen I calculate the angle between my plane and the touch location.

Now I set the "destination" angle of the plane. My "plane" is a subclass.

In my header file I have these float values:

//this is in my plane subclass
float diffAngle_; 
float startAngle_;
float dstAngle_;
float smoothRotationSpeed_;

EDIT: In my init of the layer I set the "smoothRotationSpeed" to a value. The "rotationTick" method IS scheduled. I have a tick method to rotate the plane (also in the plane subclass)

-(void)rotateTick:(ccTime)dt {

    startAngle_ = [self rotation];
    if (startAngle_ > 0)
        startAngle_ = fmodf(startAngle_, 360.0f);
    else
        startAngle_ = fmodf(startAngle_, -360.0f);

    diffAngle_ =dstAngle_ - startAngle_;
    if (diffAngle_ > 180)
        diffAngle_ -= 360;
    if (diffAngle_ < -180)
        diffAngle_ += 360;

    [self setRotation: startAngle_ + diffAngle_ * dt]; //smooth rotate

}
-(void)setSmoothRotationSpeed:(float)smoothRotationSpeed {
    [self schedule:@selector(rotateTick:)]; //this will be called if the "smoothRotationSpeed" value is changed
}

The problem is now if I touch a location the sprites rotates to it correctly but at first it rotates a little bit fast and than it looses it's speed..

The nearer it is to the destination angle the slower it moves...

But I want it to move at a constant speed. This "constant" speed is defined in the "smoothRotationSpeed" value but how can I implement it in my code?

If I set the interval to the "smoothRotationSpeed" value it wouldn't be smooth. It would lag.

Would anyone like to help me please?

Upvotes: 0

Views: 926

Answers (1)

filipe
filipe

Reputation: 3380

You're incrementing the rotation of your sprite based on the difference between the target and current angles, so the closer the current angle is to the target angle, the smaller is the increment you're applying to the current rotation. But from what you're saying, that's not what you want. So you could simply do something like this:

-(void)rotateTick:(ccTime)dt {

    startAngle_ = [self rotation];
    if (startAngle_ > 0)
        startAngle_ = fmodf(startAngle_, 360.0f);
    else
        startAngle_ = fmodf(startAngle_, -360.0f);

    diffAngle_ =dstAngle_ - startAngle_;
    if (diffAngle_ > 180)
        diffAngle_ -= 360;
    if (diffAngle_ < -180)
        diffAngle_ += 360;

    if ( fabs(diffAngle_) < smoothRotationSpeed_*dt ) // finished rotation
    {
        [self setRotation: dstAngle_]; // go to the end position
    }
    else if (diffAngle_ > 0)
    {
        [self setRotation: startAngle_ + smoothRotationSpeed_* dt]; //smooth rotate
    }
    else
    {
        [self setRotation: startAngle_ - smoothRotationSpeed_* dt]; //smooth rotate
    }
}
-(void)setSmoothRotationSpeed:(float)smoothRotationSpeed
{
    smoothRotationSpeed_ = smoothRotationSpeed;
    [self schedule:@selector(rotateTick:)]; //this will be called if the "smoothRotationSpeed" value is changed
}

Upvotes: 2

Related Questions