Rotate sprite image according to user touch location?
Asked Answered
R

3

5

I m start learning game development. As a beginner i create one demo game in which one cannon hit bullets to the enemies (coming toward cannon from different direction). Now i stuck on cannon sprite image rotation anywhere user touch on the screen or enemies. How i do that, My initial code as following,

void HelloWorld:: ccTouchesBegan(CCSet *touches, CCEvent * event)
{
    CCSize winSize = CCDirector::sharedDirector()->getWinSize(); 
    CCTouch* touch = (CCTouch*)( touches->anyObject() );
    CCPoint location = touch->locationInView(touch->view());
    location = CCDirector::sharedDirector()->convertToGL(location);

    //Rotate cannon direction toward touch point
    CCPoint diffPoint = ccpSub(_cannonImage->getPosition(), location);
    float angleRadians = atanf((float)diffPoint.y/(float)diffPoint.x);
    float angleOffset = CC_DEGREES_TO_RADIANS(180);

    if(diffPoint.x < 0){
        angleRadians += angleOffset;
    }else{
        angleRadians -= angleOffset;
    }

    CCLog("angle to be rotate = %f", angleRadians);

    _cannonImage->runAction(CCRotateBy::actionWithDuration(0.1, angleRadians));

}

The code is written in cocos2d-x . I also accepting answer by someone who written in plain cocos2d.

Thanks iHungry

Rovelli answered 16/7, 2012 at 7:49 Comment(3)
would be helpful if you mentioned what exactly is the problem with this code? Btw, check out ccpAngle and ccpAngleSigned, if they're available in cocos2d-x.Miscible
@LearnCocos2D, yes boss ... it working but it not rotate that i want....Rovelli
i m also checking changing angle.... but its not working .... the actual problem is that... the image rotating lazily and in small angle.... i want set cannon face toward the user touch location.Rovelli
R
1

First of all, replace

float angleRadians = atanf((float)diffPoint.y/(float)diffPoint.x);
float angleOffset = CC_DEGREES_TO_RADIANS(180);

if(diffPoint.x < 0){
    angleRadians += angleOffset;
}else{
    angleRadians -= angleOffset;
}

by

float angleRadians = atan2f(diffPoint.y, diffPoint.x);

Then it would be better to set rotation immediately (without actions) to process multiple frequent touches.

_cannonImage->setRotation(angleRadians);

Maybe you will need to adjust rotation like setRotation(-angleRadians) or setRotation(angleRadians+90) - it depends on your coordinate system.

Riorsson answered 17/7, 2012 at 6:13 Comment(1)
In my code I had to switch x and y to atan2f(diffPoint.x, diffPoint.y); and setRotation(angleRadians/M_PI * 180);Heppman
R
5

The perfect answer as follows,

float HelloWorld::changingAngleAccordingToCoordinateSystem(CCPoint imageCenter, CCPoint touchLocation, float calculatedAngle){

//Consideration :- all Angles is in Degree 
if((calculatedAngle >= 0 && calculatedAngle <= 90) || (calculatedAngle >= 90 && calculatedAngle <= 180)){
    //Ist quardant
    calculatedAngle = calculatedAngle;
}
else if(calculatedAngle < 0 && calculatedAngle >= -90){
    //IInd quardant
    calculatedAngle = 270 + (90 + calculatedAngle);
} 
else if(calculatedAngle < -90 && calculatedAngle >= -180){
    calculatedAngle = 180 + (180 + calculatedAngle);
}

return calculatedAngle;
}


//Rotate cannon direction toward touch point
float diff_X = touchLocation.x - myImage->getPosition().x;
float diff_Y = touchLocation.y - myImage->getPosition().y;
CCPoint diffPoint = CCPoint(diff_X, diff_Y);
float angleRadians = atan2f(diffPoint.y,diffPoint.x);
angleRadians = CC_RADIANS_TO_DEGREES(angleRadians);
angleRadians = HelloWorld::changingAngleAccordingToCoordinateSystem(myImage->getPosition(), touchLocation, angleRadians);
myImage->setRotation(-angleRadians);
Rovelli answered 17/7, 2012 at 10:52 Comment(0)
B
3

i used this code to rotate my sprite. i Was moving the sprite according to my accelerometer reading.

float angleRadians =-accelX;
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
objGlider->sprite_Glider.rotation = cocosAngle;

Check it. The reason of slow may be that you may be using CClog or NSLog in the code.

Here goes the complete code.

if(!boolPlayerDied)
{
    static float prevX=0, prevY=0;
    #define kFilterFactor 1.0f// don't use filter. the code is here just as an example
    float accelX = (float) acceleration.x * kFilterFactor + (1- kFilterFactor)*prevX;
    float accelY = (float) acceleration.y * kFilterFactor + (1- kFilterFactor)*prevY;
    prevX = accelX;
    prevY = accelY;
    accelX = accelX-0.5;// Angle check fot tgfor the player to play
    float angleRadians =-accelX;
    float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
    if(accelX>0)
    {
        cocosAngle = 1.1 * angleDegrees;
    }
    else
    {
        if(accelX<-0.5)
            accelX=-0.5;
        cocosAngle = 1.1  * angleDegrees;
    }
    objGlider->sprite_Glider.rotation = cocosAngle;
}

objGlider is the object of the class which creates glider sprite and sprite_Glider is the sprite used in glider class.

you can use rotation property with your sprite to be rotated. In cocos2Dx it might be setRotation.

Backpack answered 17/7, 2012 at 4:45 Comment(3)
can u provide me your brief code becoz i m not understanding the term of sprite_Glider.rotation...... Even though cocos2dx not accepting dot (.) syntax for rotation... we have to used either CCRotateBy or CCRotateTo classes.Rovelli
Yes Ur code also proper but accepted code work for me. I only give you up-vote for it.Rovelli
No worries. Just one question. using setRotation property with sprite, did it worked in cocos2D-x ??Backpack
R
1

First of all, replace

float angleRadians = atanf((float)diffPoint.y/(float)diffPoint.x);
float angleOffset = CC_DEGREES_TO_RADIANS(180);

if(diffPoint.x < 0){
    angleRadians += angleOffset;
}else{
    angleRadians -= angleOffset;
}

by

float angleRadians = atan2f(diffPoint.y, diffPoint.x);

Then it would be better to set rotation immediately (without actions) to process multiple frequent touches.

_cannonImage->setRotation(angleRadians);

Maybe you will need to adjust rotation like setRotation(-angleRadians) or setRotation(angleRadians+90) - it depends on your coordinate system.

Riorsson answered 17/7, 2012 at 6:13 Comment(1)
In my code I had to switch x and y to atan2f(diffPoint.x, diffPoint.y); and setRotation(angleRadians/M_PI * 180);Heppman

© 2022 - 2024 — McMap. All rights reserved.