Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotate sprite image according to user touch location?

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

like image 596
Tirth Avatar asked Jul 16 '12 07:07

Tirth


3 Answers

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);
like image 53
Tirth Avatar answered Nov 11 '22 02:11

Tirth


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.

like image 20
NiKKi Avatar answered Nov 11 '22 00:11

NiKKi


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.

like image 1
brigadir Avatar answered Nov 11 '22 02:11

brigadir