how to detect touch in a circle - cocos2d-iphone

I really assistance. Im a little confused.
i have a circle sprite, and this code
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGSize winSize =[[CCDirector sharedDirector] winSize];
UITouch* myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView: [myTouch view]];
location = [[CCDirector sharedDirector]convertToGL:location];
CCSprite *circleSprite = (CCSprite*)[self getChildByTag:30];
CGRect correctColorSprite1 = [circleSprite boundingBox];
if (CGRectContainsPoint(correctColorSprite1, location)) {
NSLog(#"inside");
}
as i know there is a bounding box, when i touch slightly outside of the top circle it will still detect the touch.
i have read in some forums that i need to detect distance of the centre of the sprite and the touch point. But i really don't know how to write that code. My circle size is around 50 points.
I hope someone can help me out give me some snippets of a improved code to detect the touch only in the circle. Not with the bounding box. Your help is very great full.

Try this:
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGSize winSize =[[CCDirector sharedDirector] winSize];
UITouch* myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView: [myTouch view]];
location = [[CCDirector sharedDirector]convertToGL:location];
CCSprite *circleSprite = (CCSprite*)[self getChildByTag:30];
//CGRect correctColorSprite1 = [circleSprite boundingBox];
CGRect correctColorSprite1 = CGRectMake(
circleSprite.position.x - (circleSprite.contentSize.width/2),
circleSprite.position.y - (circleSprite.contentSize.height/2),
circleSprite.contentSize.width,
circleSprite.contentSize.height);
//find the center of the bounding box
CGPoint center=ccp(correctColorSprite1.size.width/2,correctColorSprite1.size.height/2);
//now test against the distance of the touchpoint from the center
if (ccpDistance(center, location)<50)
{
NSLog(#"inside");
}
}

Related

Handling CCSprites with Multiple Touch

I have one or more than one sprites stored in a array. What i want is to drag these sprites with multiple fingers around the screen. i.e (Multiple Touch)
Can anyone tell me how to do that?
Any help will be appreciated..
Here is my code:
-(void)touchBegan:(CCTouch *)touch withEvent:(CCTouchEvent *)event
{
CGPoint location = [touch locationInNode:self];
selectedSprite.paused = YES;
[self selectSpriteFromTouch:location];
//this is where i get sprite selected from i.e selectedSprite from array
}
-(void)touchMoved:(CCTouch *)touch withEvent:(CCTouchEvent *)event
{
selectedSprite.position = [touch locationInNode:self];
}
-(void)touchEnded:(CCTouch *)touch withEvent:(CCTouchEvent *)event
{
selectedSprite.paused = NO;
selectedSprite.position = [touch locationInNode:self];
selectedSprite = nil;
}
-(void)touchCancelled:(CCTouch *)touch withEvent:(CCTouchEvent *)event
{
selectedSprite.paused = NO;
selectedSprite = nil;
}
If I understand correctly you want say two fingers on the screen, each to move 1 sprite? I guess you have the images in an array so get the location of each touch and if each touch is on a sprite, then you know which touch is on which sprite.
CGPoint fingerOne = [event.allTouches.allValues[0] locationInWorld];
CGPoint fingerTwo = [event.allTouches.allValues[1] locationInWorld];
If sprite at index 0 is touched by fingerOne, then you can move that by the same amount as fingerOne moves and similarly for fingerTwo and sprite at index 1.

Drag a sprite attached to a body

I have a CCSprite that is attached to body in a b2world .
When someone is touch it, i want to move it with the touch location.
With a regular sprite that works fine , but with a sprite that has a body- it does not .
it gets the touch but not move the sprite (the body follow the sprite or the opposite?)
How should i do that ? apply a force relative to the touch is a problem..
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPosition = [touch locationInView: [touch view]];
//detect a touch ont the button
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
CGPoint location=[[CCDirector sharedDirector] convertToGL: currentPosition];
CCSprite *tempSprite = (CCSprite *) b->GetUserData();
if( tempSprite.tag==2 )
{
if(CGRectContainsPoint([tempSprite boundingBox], location))
{
tempSprite.position=location;
NSLog(#"touched");
}
}
}
}
Try changing the position of the body using SetTransform function. I think it's looking something like:
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPosition = [touch locationInView: [touch view]];
//detect a touch ont the button
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
CGPoint location=[[CCDirector sharedDirector] convertToGL: currentPosition];
CCSprite *tempSprite = (CCSprite *) b->GetUserData();
if( tempSprite.tag==2 )
{
if(CGRectContainsPoint([tempSprite boundingBox], location))
{
b->SetTransform( b2Vec2( location.x/PTM_RATIO, location.y/PTM_RATIO ), 0 ); //change position of the body
NSLog(#"touched");
}
}
}
}
Don't forget, if you want to change body position apply force or set linear velocity you must use kinematic or dynamic body type.

MultiTouch control of a sprites movement - cocos2d

I've been dealing with this problem for quite some time.
What I am trying to do is have a CCSprite's right/left movement controlled by touches on either the left side of the screen or the right.
Doing this is no problem if you lift your finger after each touch. But what I want is best described by an example:
The player touches the left side of the screen and the sprite moves to the left. Now the player (while still touching the left side) touches the right side...the sprite should now move right. Now the player has one finger on the left and one on the right side, if he now lifts the touch off the right side the sprite should again move to the left.
This is what I have now:
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
//Swipe Detection Part 1
firstTouch = location;
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
//Swipe Detection Part 2
lastTouch = location;
float swipeLength = ccpDistance(firstTouch, lastTouch);
if (firstTouch.y < lastTouch.y && swipeLength > 60) {
[player jump:kkJumpUp];
} else if (firstTouch.y > lastTouch.y && swipeLength > 60){
[player jump:kkJumpDown];
}
[player endWalk];
}
I'd appreciate it if someone could tell me how to go about this. Thank you .
UPDATE MY SOLUTION:
//1. Enable multitouch in the appDelegate
[glView setMultipleTouchEnabled:YES];
//2. Create an Array to keep track of active touches
touchArray = [[NSMutableArray alloc] init];
//3. Touch Methods
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
if (![touchArray containsObject:touch]) {
[touchArray addObject:touch];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(#"start: %f", location.x);
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
}
}
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
[touchArray removeObject:touch];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(#"end: %f", location.x);
}
for (UITouch *touch in touchArray) {
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCLOG(#"still: %f", location.x);
if (location.x < 240) {
[player walk:kkMoveLeft];
} else if (location.x > 240) {
[player walk:kkMoveRight];
}
}
if ([touchArray count] == 0) {
[player endWalk];
}
}
If I understand correctly your problem, what you should do is:
in ccTouchesEnded, instead of simply calling endWalk, check to see is any touch is still present (to do so, you could iterate over allTouches);
in the appropriate case (i.e., a touch is still activating the player), call startWalk.
if no touch is present, call endWalk.
The code would be similar to what you have in ccTouchesBegan, only you iterate (I am not sure what allTouches contains at index 0 in touchesEnded).
OLD ANSWER:
You are not saying anything about how you are handling touches right now. In any case, the way to go is defining ccTouches* methods (vs. ccTouch*), where * can be: Began, Moved, Ended.
-(void)tccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
...
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
...
}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
...
}
Keep in mind that touchesBegan is fired at each new touch that is detected. So, if you want to know the status of all touches currently active, you have to use allTouches.
Have also a look at this post from iphonesdk which I found insightful as to the semantics of touches in those methods.

need help to create following motion

I want to create following motion using moveTo or MoveBy methods of cocos2d
when I touch object should move there.Is it possible in cocos2d?
(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
for( UITouch *touch in touches ) {
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
//while creating sprite set like sprite.tag=2;
CCSprite *spr=[self getChildByTag:2];//use your sprite tag while creating
id move = [CCMoveBy actionWithDuration:4 position:location];
[spr runAction:move];

Leaves falling animation and dragging along with finger

I am new to Cocos2D, could any one please tell me how we can do leaves falling from top and settled down at bottom of the iPad, when ever user tilt the iPad or touches the leaves, the leaves should respond accordingly.It should be similar to alice wonderland lite application page number 13 animation.
I am posting my code but However it doesn't behave exactly how I want. Whenever I touch near a sprite all the sprites move with incredible force.... they literally move out of the way of where I'm touching. Surely I'm not the only one who's implemented this before? Can anyone lead me in the right direction?
static float hw = 639.0/2.0, hh = 479.0/2.0;
static cpVect mouseToSpace(cpVect pos, CGSize size)
{
cpVect v = cpvsub(cpvmult(cpv(pos.y/size.height, pos.x/size.width), 2.0f), cpv(1.0f, 1.0f));
v = cpv(v.x*hw, v.y*hh);
// printf("%s\n", cpvstr(v));
return v;
}
#define GRABABLE_MASK_BIT (1<<31)
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
cpVect point = mouseToSpace([myTouch locationInView:[myTouch view]], [myTouch view].bounds.size);
mousePoint = point;
cpShape *shape = cpSpacePointQueryFirst(space, point, GRABABLE_MASK_BIT, 0);
if(shape) {
cpBody *body = shape->body;
mouseJoint = cpPivotJointNew2(mouseBody, body, cpvzero, cpBodyWorld2Local(body, point));
mouseJoint->maxForce = 50000.0f;
mouseJoint->biasCoef = 0.15f;
cpSpaceAddConstraint(space, mouseJoint);
}
}
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
mousePoint = mouseToSpace([myTouch locationInView:[myTouch view]], [myTouch view].bounds.size);
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesCancelled:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
cpSpaceRemoveConstraint(space, mouseJoint);
cpConstraintFree(mouseJoint);
mouseJoint = nil;
}
Any one please guide me or post the code, i need it urgently.
Waiting for your valuable suggestions and any code.
Thanks in advance.
Shiva.
Cocos2d comes with projects to get you started. One of these is "Cocos2d with Box2D". This project starts you off with a scene that spawns a load of boxes at the top which fall to the bottom of the screen using the Box2D physics. If I remember correctly, it also shifts them around when you tilt.
Look at that project and adapt it to suit your needs.
This blog was my invaluable go-to resource when starting off with iPhone games development. I suggest you read it.