curved line in cocos2d - iphone

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];
}
}

Related

How To select all the targets with touches rect in cocos2d

i want to select my targets using touches rect
am creating my unselected dots by coding like these:-
targets1 = [[NSMutableArray alloc] init];
for(int i=0;i<3;i++)
{
for (int y=0; y<3; y++) {
CCTexture2D *texture =
[[CCTextureCache sharedTextureCache] addImage:#"UnselectedDot.png"];
block = [CCSprite spriteWithTexture:texture rect:CGRectMake(0,0,82,82)];
CGFloat xoffset = ((block.contentSize.width)*10) + (((block.contentSize.height)-175)*y);
block.position = ccp( (i*82)+80,xoffset);
[bg1 addChild:block];
[targets1 addObject:block];
}
}
below is my sample output .
now i need to select all the dots by touches method. i written coding like these:-
- (void)update:(ccTime)dt {
// NSLog(#"%#",targets1);
for (CCSprite *sprite in targets1) {
CGRect dotrect = CGRectMake(sprite.position.x,
sprite.position.y-95,
sprite.contentSize.width,
sprite.contentSize.height);
CGFloat x = location.x;
CGFloat y = location.y;
CGFloat width = (location1.x - location.x);
CGFloat height = -(location1.y - location.y);
CGRect touchrect = CGRectMake (x, y, width,height);
NSLog(#"dotrect = %f,%f,%f,%f",dotrect.origin.x,dotrect.origin.y,dotrect.size.width,dotrect.size.height );
NSLog(#"touch rect = %f,%f,%f,%f,%f,%f",touchrect.origin.x,touchrect.origin.y,touchrect.size.width,touchrect.size.height,location1.x,location1.y);
if( CGRectContainsRect(dotrect, touchrect))
{ //collision detection
NSLog(#"am touched dot ");
}
}
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
NSLog(#"am touched began");
return YES;
}
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
location1 = [touch locationInView:[touch view]];
location1 = [[CCDirector sharedDirector] convertToGL:location1];
location1 = [self convertToNodeSpace:location1];
}
as per above coding my concept is :- using touches began and touches ended am making rectangle here.. inside these touchrect my unselected dot rect came means collsison detected.. then i can do my stuffs there. but its not colliding all.
am not getting were am making mistake.
Edit :1
now i got why coillision not working... actually insidemy touches rect having multiple rect.. so only ... here, am using rectcontainsrect.. tahts the problem.. any other method to rect having several rect for colllsion detection..
Try using:
CGPoint location=[touch locationInView:[touch view]];
location = [self convertTouchToNodeSpace:touch];
CGRectContainsPoint([dot boundingBox], location);
inside the CCTouch.. methods (as you wish depending on what you want to do).

Rotating a sprite with Touch - Cocos2d

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

objective-c iPhone game programming : detect touch on tile map object layer

hi made an object layer on my tile map with tile map editor like this :
http://i.stack.imgur.com/f5fZK.png
The big square represent my object layer named : ObjectIt.
My problem is when i touch the square in the simulator it doesn't correspond to the right place. Some people told me problem with float value or open gl but I'm noob i need clear answers .
This is my code :
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touch detect");
CCNode* node = [self getChildByTag:TileMapNode];
NSAssert([node isKindOfClass:[CCTMXTiledMap class]], #"not a CCTMXTiledMap");
CCTMXTiledMap* tileMap = (CCTMXTiledMap*)node;
// Get the position in tile coordinates from the touch location
CGPoint touchLocation = [self locationFromTouches:touches];
CGPoint tilePos = [self tilePosFromLocation:touchLocation tileMap:self.tileMap];
// Check if the touch was on water (e.g., tiles with isWater property)
bool isTouchOnWater = NO;
CCTMXObjectGroup* objectLayer = [tileMap objectGroupNamed:#"ObjectIt"];
bool isTouchInRectangle = NO;
int numObjects = [objectLayer.objects count];
for (int i = 0; i < numObjects; i++)
{
NSDictionary* properties = [objectLayer.objects objectAtIndex:i];
CGRect rect = [self getRectFromObjectProperties:properties tileMap:tileMap];
if (CGRectContainsPoint(rect, touchLocation))
{
isTouchInRectangle = YES;
break; }
}
if (isTouchInRectangle)
{
NSLog(#"TOUCH IN RECTANGLE");
// get the ALGORITH FOR TOWERS
}
}
-
(CGPoint) locationFromTouch:(UITouch*)touch
{
CGPoint touchLocation = [touch locationInView: [touch view]];
return [[CCDirector sharedDirector] convertToGL:touchLocation];
}
-(CGPoint) locationFromTouches:(NSSet*)touches
{
return [self locationFromTouch:[touches anyObject]];
}
-(CGRect) getRectFromObjectProperties:(NSDictionary*)dict
tileMap:(CCTMXTiledMap*)tileMap
{
float x, y, width, height;
x = [[dict valueForKey:#"x"] floatValue] + tileMap.position.x;
y = [[dict valueForKey:#"y"] floatValue] + tileMap.position.y;
width = [[dict valueForKey:#"width"] floatValue];
height = [[dict valueForKey:#"height"] floatValue];
return CGRectMake(x, y, width, height);
}
Thats the code , ill give you more if you need.
Also : when i run on the iPhone i got vertical black lines...
In order to get the correct touch location in Cocos2D points use this CCNode convenience method:
- (CGPoint)convertTouchToNodeSpace:(UITouch *)touch
{
CGPoint point = [touch locationInView: [touch view]];
point = [[CCDirector sharedDirector] convertToGL: point];
return [self convertToNodeSpace:point];
}
I'm not sure if it's been added to the API since phix23 posted their answer but the convertTouchToNodeSpace: method basically does the same thing:
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CCTMXTiledMap* tileMap = (CCTMXTiledMap*)[self getChildByTag:TileMapNode];
CGPoint p = [tileMap convertTouchToNodeSpace:touch];
// If you wanted to figure out which tile in a layer they touched (assuming
// it's Ortho) you could do something like this:
CCTMXLayer *layer = [tileMap layerNamed:#"Tile Layer 1"];
CGPoint q = {
(int) (p.x / tileMap.tileSize.width),
// World origin is bottom left but map coordinates are top left so flip
// the y.
layer.layerSize.height - (int) (p.y / tileMap.tileSize.height) - 1
};
CCSprite *s = [layer tileAt:q];
NSLog(#"Touched %#", s);
return YES;
}

Limit Sprite Rotation - Cocos2d

I have two hands on either side of the screen that do not move at all and two thumbs that rotate 360 degrees. I want to limit the thumbs rotation, meaning I only need them to be able to rotate like normal thumbs. I am new to cocos2d so any help will be greatly appreciated. Here is what I have so far
#import "cocos2d.h"
#interface GameScene : CCLayer {
CGFloat lthumbRotation, rthumbRotation;
CCSprite *lthumb, *rthumb;
}
+(CCScene *) scene;
#end
------------------------------------
#import "GameScene.h"
#implementation GameScene
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
GameScene *layer = [GameScene node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if ((self = [super init]))
{
lthumb = [CCSprite spriteWithFile:#"lthumb.png" rect:CGRectMake(0,0, 145, 59)];
lthumb.position = ccp(100, 140);
lthumb.anchorPoint = ccp(0.3, 0.8);
[self addChild:lthumb z:0];
rthumb = [CCSprite spriteWithFile:#"rthumb.png" rect:CGRectMake(0,0, 145, 59)];
rthumb.position = ccp(380, 140);
rthumb.anchorPoint = ccp(0.7, 0.8);
[self addChild:rthumb z:0];
[self scheduleUpdate];
}
return self;
}
-(void)update:(ccTime)delta
{
lthumb.rotation = lthumbRotation;
rthumb.rotation = rthumbRotation;
}
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (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, rthumb.position);
CGFloat firstRotateAngle = -ccpToAngle(firstVector);
CGFloat previousTouch = CC_RADIANS_TO_DEGREES(firstRotateAngle);
CGPoint vector = ccpSub(touchingPoint, rthumb.position);
CGFloat rotateAngle = -ccpToAngle(vector);
CGFloat currentTouch = CC_RADIANS_TO_DEGREES(rotateAngle);
//keep adding the difference of the two angles to the dial rotation
lthumbRotation += currentTouch - previousTouch;
rthumbRotation -= currentTouch - previousTouch;
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void) dealloc
{
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
[super dealloc];
}
#end
This lets both of the thumbs move at the same time in upward/downward angles with the anchor point at the bottom of the thumbs(acting like a joint).
I also need the thumbs rotation to reset back to 0 once the touches have ended.
Thanks in advance
In your ccTouchesMoved:withEvent: method, simply check to see if the new rotation is within a given threshold before applying it to your sprites.
Finally, in ccTouchesEnded:withEvent:, you can simply set the rotation values back to 0:
lthumbRotation = 0;
rthumbRotation = 0;

Detecting if a specific sprite was touched on Cocos2d-iphone

I was following Ray`s tutorial for making a simple iPhone game (here: http://goo.gl/fwPi) , and decided that i wanted the enemies to be eliminated when they get touched.
My initial approach was to spawn a small CCSprite sprite on the touch location, then use CGRectMake to create a bounding box of said sprite to detect if the enemy sprite was touched. Much like Ray does with the projectile/enemy. But of course, my way of doing it isnt working and i cant dig myself out of this hole.
Here is the relevant code snippet. Any help is appreciated:
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [self convertTouchToNodeSpace: touch];
location = [[CCDirector sharedDirector] convertToGL:location];
CCSprite *touchedarea = [CCSprite spriteWithFile:#"Icon-72.png" rect:CGRectMake(location.x, location.y, 2, 2)];
touchedarea.tag = 2;
[self addChild:touchedarea];
[_touchedareas addObject:touchedarea];
}
- (void)update:(ccTime)dt {
NSMutableArray *touchedareasToDelete = [[NSMutableArray alloc] init];
for (CCSprite *touchedarea in _touchedareas) {
CGRect touchedareaRect = CGRectMake(
touchedarea.position.x,
touchedarea.position.y,
touchedarea.contentSize.width,
touchedarea.contentSize.height);
NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init];
for (CCSprite *target in _targets) {
CGRect targetRect = CGRectMake(
target.position.x - (target.contentSize.width/2),
target.position.y - (target.contentSize.height/2),
target.contentSize.width,
target.contentSize.height);
if (CGRectIntersectsRect(touchedareaRect, targetRect)) {
[targetsToDelete addObject:target];
}
}
for (CCSprite *target in targetsToDelete) {
[_targets removeObject:target];
[self removeChild:target cleanup:YES];
}
if (targetsToDelete.count > 0) {
[touchedareasToDelete addObject:touchedarea];
}
[targetsToDelete release];
}
for (CCSprite *touchedarea in touchedareasToDelete) {
[_touchedareas removeObject:touchedarea];
[self removeChild:touchedarea cleanup:YES];
}
[touchedareasToDelete release];
}
That looks like a very difficult way to go about doing it. I havent been coding long myself but maybe the following might help you.
lets say u have a nsmutablearray called enemies and you add the new enemy object to this array when ever you create one. enemy object would be a ccnode and have a ccsprite within it called _enemySprite
then do the touch
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
//UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
int arraysize = [enemies count];
for (int i = 0; i < arraysize; i++) {
if (CGRectContainsPoint( [[[enemies objectAtIndex:i] _enemySprite] boundingBox], location)) {
//some code to destroy ur enemy here
}
}
// NSLog(#"TOUCH DOWN");
}
hope this helps
Another way of doing it is that calculating distance between touch position and your sprites.. If touch is close enough to one of your sprites, you can kill it.. Something like this..
for (CCSprite *sprite in anArrayThatCOntainsAllYourSprites) {
float distance = pow(sprite.position.x - location.x, 2) + pow(sprite.position.y - location.y, 2);
distance = sqrt(distance);
if (distance <= 10) {
sprite.dead = YES;
}
}