Rotate sprite image according to user touch location? - iphone

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

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);

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.

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.

Related

Unity track object rotation

I have several object rotating by itself in FixedUpdate().
Now I need to track rotation of one object, lets call it objX. Rotation goes only from 0 to 360 when I retrieve it. Is it possible to get rotation after 360 degrees?
For example when I use something like
float x = objX.transform.rotation.z;
variable x should be 560 degrees.
Is something like that possible?
Here is the way to track rotation.
Vector3 mouseClickPos;
float angle;
float lastAngle;
int fullRotations;
public float realAngle;
void FixedUpdate(){
mouseClickPos = Input.mousePosition;
Vector3 dir = mouseClickPos - Camera.main.WorldToScreenPoint(transform.position);
angle = Mathf.Atan2(dir.y,dir.x) * Mathf.Rad2Deg;
angle-=90;
if(lastAngle - angle > 270){
fullRotations ++;
}else if(angle - lastAngle > 270){
fullRotations --;
}
Debug.Log(360*fullRotations + angle);
Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.RotateTowards(transform.rotation, q, 6);
lastAngle = angle;
}

Rotating device while using accelerometer

I'm using accelerometer in my first Cocos2D game and it work fine, i'm able to move the sprite using the below code however, when i change the orientation from landscapeLeft to landscapeRight, the sprite stops responding to Y coordination, and the sprite goes to the top of the screen and doesn't properly respond... I believe it's because of changing the device orientation, but i'm not sure since i'm pretty new to App Development, any help will be appreciated.
Here is the sample code i'm using...
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
//this determines how sensitive the accelerometer reacts (higher = more sensitive)
NSUserDefaults *defaulObj = [NSUserDefaults standardUserDefaults];
float sensitivity = [defaulObj floatForKey:#"Sensitivity"]; //10.0f
if (!sensitivity) {
sensitivity = 6;
}
// this controls how quickly the velocity decelerates (lower = quicker to change direction)
float deceleration = 0.4f;
static float xVal = 0;
if (!self.isFlag) {
xVal = -acceleration.x;
self.isFlag = TRUE;
}
playerVelocity.x = playerVelocity.x * deceleration + (xVal + acceleration.x) * sensitivity;
playerVelocity.y = playerVelocity.y * deceleration + acceleration.y * sensitivity;
playerVelocity.y = playerVelocity.y*-1;
}
Perhaps this helps out, flips Y along your current device orientation.
float rotatedY = acceleration.y;
if ([UIApplication sharedApplication].statusBarOrientation==UIInterfaceOrientationLandscapeLeft) {
rotatedY *= -1;
}
then use rotatedY insteat of acceleration.y

how use Accelerometer in Landscape in iphone/ipad

i am working on game in which i want to move CCSprite in direction of accelerometer tilt.i have referred this tutorial http://www.raywenderlich.com/457/intro-to-box2d-with-cocos2d-tutorial-bouncing-balls but i am not clear with it. Please can any one help me.
Thanks in Advance.
Refer this solution. I used same for moving sprite from left to right in landscape game.: See answer here
Only change for landscape mode is use accelerometer y in place of x.
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
if(self.isGamePaused || self.isGameOver)
return;
float deceleration = 1.0f, sensitivity = 15.0f, maxVelocity = 450;
if(sGame.IsIpad)
{
sensitivity = 14.0f;
maxVelocity = 850;
deceleration = 1.5f;
}
// adjust velocity based on current accelerometer acceleration
// vel.x = vel.x * deceleration + acceleration.x * sensitivity;
AppController *app = (AppController*)[UIApplication sharedApplication].delegate;
float velocity_x = self.gameActor.velocity.x ;
self.gameActor.accelVal = ABS(acceleration.y);
if(app.orient == UIInterfaceOrientationLandscapeLeft)
{
velocity_x = velocity_x * deceleration + acceleration.y * sensitivity;
}
else
{
velocity_x = velocity_x * deceleration + (-acceleration.y) * sensitivity;
}
//limit the maximum velocity of the player sprite, in both directions (positive & negative values)
velocity_x = fmaxf(fminf(velocity_x, maxVelocity), -maxVelocity);
self.gameActor.velocity = ccp(velocity_x, self.gameActor.velocity.y);
}

sprite not rotating correctly (cocos2d)

I have a turret on top of a tank base, both inside the same sprite sheet with frames correctly specified. When i build and run the project, I want the turret to rotate along the anchor point of the center of the tank. The turret is a child of the tank so that they will stay together when moving. However, when I try to rotate it, the turret seems to set its anchor point somewhere far off into the distance, like this:
This is my init:
- (id)initWithLayer:(HelloWorldLayer *)layer type:(int)type hp:(int)hp {
NSString *spriteFrameName = [NSString stringWithFormat:#"tank%d_base.png", type];
if ((self = [super initWithSpriteFrameName:spriteFrameName])) {
_layer = layer;
_type = type;
self.hp = hp;
_turret = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:#"tank%d_turret.png", type]];
_turret.anchorPoint = ccp(0.5, 0.25);
[self scheduleUpdateWithPriority:-1];
[self addChild:_turret];
_turret.position = ccp(40, 50);
}
return self;
}
and I rotate the sprite here (I use a 360 degree shooting range)
- (void)shootToward:(CGPoint)targetPosition {
//CGPoint offset = ccpSub(targetPosition, self.position);
float x = abs(targetPosition.x) - self.position.x;
float y = abs(targetPosition.y) - self.position.y;
float angle;
float angleDegrees;
if (x < 0 && y > 0) {
angle = atanf(y/x);
angleDegrees = -CC_RADIANS_TO_DEGREES(angle) - 90;
}
else if (x < 0 && y < 0) {
angle = atanf(y/x);
angleDegrees = -CC_RADIANS_TO_DEGREES(angle) - 90;
}
else if (x > 0 && y < 0) {
angle = atanf(y/x);
angleDegrees = 90 - CC_RADIANS_TO_DEGREES(angle);
}
else if(x > 0 && y > 0) {
angle = atanf(y/x);
angleDegrees = 90 - CC_RADIANS_TO_DEGREES(angle);
}
switch (_layer.rotateInt) {
case 0:
angleDegrees = angleDegrees;
break;
case 1:
angleDegrees = angleDegrees+ 180;
break;
case 2:
angleDegrees = angleDegrees;
break;
case 3:
angleDegrees = angleDegrees + 90;
break;
case 4:
angleDegrees = angleDegrees - 90;
break;
default:
break;
}
NSLog(#"%f",angleDegrees);
_turret.rotation = angleDegrees;
Hmm. The only thing that I think could be causing this is that the turret asset is not centered or has a lot of blank space. That said, I'd try playing with the anchor point of the turret.
Since the turret is a child of the tank, this:
_turret.position = ccp(40, 50);
offsets the turret by 40x50 away from the tank's origin (lower left corner of bounding box). Try settings the position so the turret is centered on the tank:
_turret.position = ccp(tank.contentSize.width * tank.anchorPoint.x,
tank.contentSize.height * tank.anchorPoint.y);

Accelerometer in Box2D

I am new in Box2D....
I have ball image in CCSprite. I want to move ball in whole screen using accelerometer...
tell me
How to use accelerometer in box2d??
Thanks...in advance
The standard cocos2d-box2d template file moves boxes using the accelerometer by applying gravity relative to the accelerometer value.
- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
static float prevX=0, prevY=0;
//#define kFilterFactor 0.05f
#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;
// accelerometer values are in "Portrait" mode. Change them to Landscape left
// multiply the gravity by 10
b2Vec2 gravity( -accelY * 10, accelX * 10);
world->SetGravity( gravity );
}
You need to be more specific on what you want the ball to do dependent on how you move the phone. Your question is difficult to answer in its current form.
Get the accelerometer measurements and say Force = coefficient*measurements. The apply this force to your b2Body
Let your Ball Sprite having tag is 1.
Replace this code with your Accelerometer delegate,
I test it on device, its working.
and your ball will move with accelerometer.
-(void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
#define kFilterFactor 0.75
accelerometer.updateInterval = 1.0f/60.0f;
static UIAccelerationValue rollingX = 0, rollingY = 0;
for (b2Body *b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL)
{
CCSprite *sprite = (CCSprite*)b->GetUserData();
if (sprite.tag == 1) {
rollingX = (acceleration.x * kFilterFactor) + (rollingX * 0.25);
rollingY = (acceleration.y * kFilterFactor) + (rollingY * 0.25);
float accelX = rollingX;
float accelY = rollingY;
CGPoint moveNewPosition = sprite.position;
if (accelX > 0.1) {
moveNewPosition.y += 2;
} if (accelX < 0.1) {
moveNewPosition.y -= 2;
}
if (accelY > 0.1) {
moveNewPosition.x -= 2;
} if (accelY < -0.1) {
moveNewPosition.x += 2;
}
b->SetLinearVelocity(b2Vec2(2,2));
sprite.position = ccp(moveNewPosition.x , moveNewPosition.y );
sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
}
I hope it'll work.