Rotating a sprite with Touch - Cocos2d - iphone

I know this question has been asked several times, trust me I have searched. I have found one answer to rotating a sprite with touch, but there has to be a simpler way.
All I need is for my sprite to rotate with my touch. Max rotation 0 Minimum rotation 0.
I know that I'll need a few checks.
int maxRot = 0;
int minRot = 0;
if (arrowRotation > maxRot)
{
//do or don't do something
} else if (arrowRotation < minRot)
{
//do or don't do something
}
Can someone lead me in the right direction to rotating a sprite with touch, with a minimun and maximum rotation?
Here is the code that I think is to complicated or can be accomplished in a simpler way.
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
//acquire the previous touch location
CGPoint firstLocation = [touch previousLocationInView:[touch view]];
CGPoint location = [touch locationInView:[touch view]];
//preform all the same basic rig on both the current touch and previous touch
CGPoint touchingPoint = [[CCDirector sharedDirector] convertToGL:location];
CGPoint firstTouchingPoint = [[CCDirector sharedDirector] convertToGL:firstLocation];
CGPoint firstVector = ccpSub(firstTouchingPoint, _arrow.position);
CGFloat firstRotateAngle = -ccpToAngle(firstVector);
CGFloat previousTouch = CC_RADIANS_TO_DEGREES(firstRotateAngle);
CGPoint vector = ccpSub(touchingPoint, _arrow.position);
CGFloat rotateAngle = -ccpToAngle(vector);
CGFloat currentTouch = CC_RADIANS_TO_DEGREES(rotateAngle);
//keep adding the difference of the two angles to the dial rotation
arrowRotation += currentTouch - previousTouch;
}
Thanks in advance!

I dont think you can simplify the rotation into anything simpler. I honestly didnt get how you want to both the minimum and the maximum rotations to be zero. They cant be same value. If you want to limit the rotation to a maximum and minimum add the following to the end of your ccTouchesMoved: method:
if (arrowRotation >= maxRot) {
arrowRotation = maxRot;
}
else if (arrowRotation <= minRot) {
arrowRotation = minRot;
}

use KTOneFingerRotationGestureRecognizer...
KTOneFingerRotationGestureRecognizer *rotation;
rotation = [[KTOneFingerRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotating:)];
[[self Wheel] addGestureRecognizer:rotation];
[rotation release];
Method
- (void)rotating:(KTOneFingerRotationGestureRecognizer *)recognizer {
view = [recognizer view];
if(isRotating == FALSE) {
[view setTransform:CGAffineTransformRotate([view transform], [recognizer rotation])];
}
}

Related

curved line in cocos2d

I have to develop curved line in cocos2d.Curved is similler to finger rotaion that is some of top spirits curved as per touch location.
i have an array of 50 spirit point array.if we move first spirit (in code BG_Sprite3) , want to set 1st,2nd,3rd,....50th spirit position (in code BG_Sprite2)and rotation as per touchlocation .if we move more deep(IF Y IS LESS )then rotation and position of BG_Sprite2 is also change.just like a Finger bend and Finger rotation.
This is my code ..haft of code working.but not getting curved rotation of BG_Sprite2.
-(id) init
{
if( (self=[super init]))
{
aPoints = [[NSMutableArray alloc]init];
[self removeChild:BG_Sprite2 cleanup:YES];
int m=100,n=80;
for(int i=0;i<25;i++)
{
BG_Sprite2 = [CCSprite spriteWithFile:#"nodeConnectorWhite.png"];
BG_Sprite2.position = ccp(m,n);
m=m+5;
n=n+5;
BG_Sprite2.rotation=135;
[self addChild:BG_Sprite2];
[aPoints addObject:[NSValue valueWithCGPoint:ccp(m,n)]];
}
[self removeChild:BG_Sprite3 cleanup:YES];
BG_Sprite3 = [CCSprite spriteWithFile: #"connection_green.png"];//This is first spirit
BG_Sprite3.position=ccp(235, 215);
[BG_Sprite3 setRotation:135];
[self addChild:BG_Sprite3];
}
}
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch * touch = [touches anyObject];
NSMutableArray *apointsarray = [[NSMutableArray alloc]init];
CGPoint movedtouchLocation = [touch locationInView: [touch view]];
movedtouchLocation = [[CCDirector sharedDirector] convertToGL: movedtouchLocation];
int xDiff= movedtouchLocation.x-225;//angle between first spirit and touch location
int yDiff= movedtouchLocation.y-205;
for(int i=0;i<[aPoints count];i++)
{
float angle2 = atan2f(xDiff, yDiff);
angle2 = CC_RADIANS_TO_DEGREES(angle2); // convert to degrees
angle2 -= 90; // rotate
angle2 *= -1; // clockwise
BG_Sprite2 = [CCSprite spriteWithFile:#"nodeConnectorWhite.png"];
BG_Sprite2.position =movedtouchLocation;
[BG_Sprite2 setRotation:angle2];
[self addChild:BG_Sprite2];
}
}

Apply Linear Impulse to Rotation of Sprite- Cocos2d/Box2D

I have an arrow and a ball. The anchorPoint for the arrow is on the bottom. All I need to do is have the sprite be able to rotate with touch, then a linear impulse is applied to the ball and shot in the direction the arrow is pointing to.
E.G.
Say you rotate the arrow 70 degrees then press the fire button. The ball is then shot in a 70 degree angle.
Currently, this is what I am using but the ball does not shoot in the direction the arrow is pointing too.
Rotates arrow with touch.
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
//acquire the previous touch location
CGPoint firstLocation = [touch previousLocationInView:[touch view]];
CGPoint location = [touch locationInView:[touch view]];
//preform all the same basic rig on both the current touch and previous touch
CGPoint touchingPoint = [[CCDirector sharedDirector] convertToGL:location];
CGPoint firstTouchingPoint = [[CCDirector sharedDirector] convertToGL:firstLocation];
CGPoint firstVector = ccpSub(firstTouchingPoint, _arrow.position);
CGFloat firstRotateAngle = -ccpToAngle(firstVector);
CGFloat previousTouch = CC_RADIANS_TO_DEGREES(firstRotateAngle);
CGPoint vector = ccpSub(touchingPoint, _arrow.position);
CGFloat rotateAngle = -ccpToAngle(vector);
CGFloat currentTouch = CC_RADIANS_TO_DEGREES(rotateAngle);
//keep adding the difference of the two angles to the dial rotation
arrowRotation += currentTouch - previousTouch;
}
Fire Button to shoot the ball in the direction the arrow is pointing too.
-(void) fireBall: (id)sender
{
[self unscheduleUpdate];
direction = arrowRotation;
b2Vec2 force = b2Vec2(direction, 24.8);
_ballBody->ApplyLinearImpulse(force, _ballBody->GetWorldCenter());
}
Any help is greatly appreciated!
Thanks in advance!
The impulse you are applying to the ball is (direction, 24.8). Should it not be: (direction.x * 24.8, direction.y * 24.8). This may not be the only problem, but it's one that jumped out at me.

Rotating Sprite with Touch - Cocos2d

Does anyone have a better way to rotate a sprite with one finger? My problem is that I can not get the sprite to stop rotating after it has been fully rotated twice and I flip my screen 180 degree periodcally (self.rotation = 180;) then flip it back (self.rotation = 0). But, when I flip it to 180 degrees the sprite will not rotate properly.
Any one have any better ideas than this?
CGFloat gRotation;
- (void)update:(ccTime)delta
{
g.rotation = gRotation;
}
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
if (CGRectContainsPoint(g.boundingBox, location))
{
CGPoint firstLocation = [touch previousLocationInView:[touch view]];
CGPoint location = [touch locationInView:[touch view]];
CGPoint touchingPoint = [[CCDirector sharedDirector] convertToGL:location];
CGPoint firstTouchingPoint = [[CCDirector sharedDirector] convertToGL:firstLocation];
CGPoint firstVector = ccpSub(firstTouchingPoint, g.position);
CGFloat firstRotateAngle = -ccpToAngle(firstVector);
CGFloat previousTouch = CC_RADIANS_TO_DEGREES(firstRotateAngle);
CGPoint vector = ccpSub(touchingPoint, g.position);
CGFloat rotateAngle = -ccpToAngle(vector);
CGFloat currentTouch = CC_RADIANS_TO_DEGREES(rotateAngle);
gRotation += currentTouch - previousTouch;
}
}
Thanks
EDIT:
I went in to GameConfig.h and changed #define GAME_AUTOROTATION kGameAutorotationUIViewController to #define GAME_AUTOROTATION kGameAutorotationNone
Then, went in to AppDelegate.m and changed #if GAME_AUTOROTATION == kGameAutorotationUIViewController to #if GAME_AUTOROTATION == kGameAutorotationNone
That fixed the sprite's rotation when I flipped the screen, but I am still having problems stopping the sprite's rotation after two full rotations.
add a new line at the end:
gRotation += currentTouch - previousTouch;
gRotation = fmod(gRotation,360.0); // <<< fix the angle
this maybe fix your problem, because the angle will stay in the 360 range
Other way to rotate with one finger is the UIPanGestureRecognizer (but you still need to keep the angle in the 360 range):
UIPanGestureRecognizer *gestureRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:layer action:#selector(handlePanFrom:)] autorelease];
[[[CCDirector sharedDirector] openGLView] addGestureRecognizer:gestureRecognizer];
...
- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:recognizer.view];
...
}
Take a look at this tutorial for more details (its on drag, but show how to do the pan gesture):
http://www.raywenderlich.com/2343/how-to-drag-and-drop-sprites-with-cocos2d

Moving CCLayer with "ccTouchesMoved" works but it needs some tweaks I can't figure it out

my code:
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
//Add a new body/atlas sprite at the touched location
for( UITouch *touch in touches ) {
CGPoint touchLocation = [touch locationInView: [touch view]];
CGPoint prevLocation = [touch previousLocationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
prevLocation = [[CCDirector sharedDirector] convertToGL: prevLocation];
CGPoint diff = ccpSub(touchLocation,prevLocation);
[self setPosition: ccpAdd(self.position, diff)];
}
}
This code lets me move the layer with my fingers. That works fine. But now I want to let the user only move the layer within a predefined CGRect. How to do that?
For example:
CGRect rect = CGRectMake(0,0,600,320);
Now the player should be only allowed to move the layer within this rect. In that example he could only move it (on an ipod touch) to the left and right. (till 600px).
What do I need to change to achieve that?
Thank you for any help.
Have a nice day :)
Keep a variable to check.. eg..
distmoved = distmoved + touchlocation.x - prevlocation.x;
if(distmoved<600)
//move code
note that distmoved is a float..
You should make your own check. It's not hard in your case:
[self setPosition: ccpAdd(self.position, diff)];
if (self.position.x < minX)
{
//correct x position
}
if (...)
// ...
// ans so on

Multitouch don't work in cocos2d

This is my ccTouchesMoved method.
Whats wrong? I use cocos2d framework.
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CCNode *sprite = [self getChildByTag:kTagPlayer];
CCNode *sprite2 = [self getChildByTag:kTagEnemy];
CGPoint point;
//Собрать все касания.
NSSet *allTouches = [event allTouches];
for (UITouch *touch in allTouches)
{
point = [touch locationInView:[touch view]];
point = [[CCDirector sharedDirector] convertToGL:point];
if (point.y > 384)
{
if (point.x > 992)
sprite2.position = ccp(992, size.height - 100);
else if (point.x < 32)
sprite2.position = ccp(32, size.height - 100);
else
sprite2.position = ccp(point.x, size.height - 100);
}
else
{
if (point.x > 992)
sprite.position = ccp(992, 100);
else if (point.x < 32)
sprite.position = ccp(32, 100);
else
sprite.position = ccp(point.x, 100);
}
}
}
Have you enabled multiple touches in your glView? By default the glView is instantiated in the app delegate. The code is below.
[glView setMultipleTouchEnabled:YES];
In case you're developing a Retina display App, be aware that all coordinates are in points, not pixels. So even on a Retina display with 960x640 pixels the coordinates in points (your touch location) will be in the range 480x320.
If you want to use pixels, use the "InPixels" version of all coordinates, in this case:
sprite.positionInPixels = ccp(992, 100);
If that's not the problem you should add to your post what the expected outcome is and what happens instead. A little context goes a long way.
What does the debugger say is in allTouches? You could try getting all the touches for the view like this instead:
UITouch* touch = [touches anyObject];
NSSet* allTouches = [touches setByAddingObjectsFromSet:[event touchesForView:[touch view]]];