views:

6755

answers:

6

I am developing a 2d game for iPhone by using cocos2d.

I use many small sprite (image) in my game. I want to touch two similar types of sprite(image) and then both sprite(image) will be hidden.

How can I detect touch in a specific sprite(image) ?

+6  A: 

In your layer that contains your sprite, you need to say:

self.isTouchEnabled = YES;

then you can use the same events that you would use in a UIView, but they're named a little differently:

- (void)ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
   UITouch* touch = [touches anyObject];
  //in your touchesEnded event, you would want to see if you touched
  //down and then up inside the same place, and do your logic there.
}
Jonas
this is not my answer . I want to detect a particular touch.
Nahid
I'm not sure what you mean...which particular touch?
Jonas
+5  A: 

Following Jonas's instructions, and adding onto it a bit more ...

- (void)ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
   UITouch* touch = [touches anyObject];
   CGPoint location = [[[Director sharedDirector] convertCoordinate: touch.location];
   CGRect particularSpriteRect = CGMakeRect(particularSprite.position.x, particularSprite.position.y, particularSprite.contentSize.width, particularSprite.contentSize.height);
   if(CGRectContainsPoint(particularSpriteRect, location)) {
     // particularSprite touched
     return kEventHandled;
   }
}

You may need to adjust the x/y a little to account for the 'centered positioning' in Cocos

David Higgins
+1 for teaching me that CGRectContainsPoint works in CocosLand.
Genericrich
Cocos2D, since 0.7.1 (or 0.7.2?) now uses CCP (CGPoint) instead of the CPV (Chipmunk Vector) for it's coordinates. They are interchangeable, however - afaik, they've always been since they are defined the same way. Most any of the CG* methods should work.
David Higgins
It doesn't seem like this will handle sprites that have been scaled since Sprite.contentSize is the entire contents unscaled... Though I haven't tried it yet.
Dad
A: 

@Genericrich: CGRectContainsPoint works in CocosLand because of the call 2 lines above:

[[Director sharedDirector] convertCoordinate:]

The Cocos2D objects will be using the OpenGL coordinate system, where 0,0 is the lower left, and UIKit coordinates (like where the touch happened) have 0,0 is upper left. convertCoordinate: is making the flip from UIKit to OpenGL for you.

BigSprocket
that is an inaccurate statement - it does not convert from OpenGL to UIKit ... but rather from OpenGL View Space to Screen Space as the unconverted coordinates have rather ridiculous values. Also, CocosNode objects are anchored in the center by default (0,0 == center of object) The value returned is simply a point on the screen, relative to Cocos2D Space. convertCoordinate is written as: int newY = openGLView_.frame.size.height - p.y; int newX = openGLView_.frame.size.width - p.x; CGPoint ret; switch(deviceOrientation_) { // various cases to swap around for orientation reasons } return ret;
David Higgins
+1  A: 

@david, your code has some typos for cocos 0.7.3 and 2.2.1, specifically CGRectMake instead of CGMakeRect and [touch location] is now [touch locationInView:touch.view].

here's what I did:

- (BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch * touch = [touches anyObject];

    CGPoint location = [[Director sharedDirector] convertCoordinate: [touch locationInView:touch.view]];
    CGRect myRect = CGRectMake(sprite.position.x, sprite.position.y, sprite.contentSize.width, sprite.contentSize.height);


    if(CGRectContainsPoint(myRect, location)) {
     // particularSprite touched
     return kEventHandled;
    }
}
John
A: 

Here's how it worked for me... Where spriteSize is obviously the sprite's size... :P

- (BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch * touch = [touches anyObject];

    CGPoint location = [[Director sharedDirector] convertCoordinate: [touch locationInView:touch.view]];
    CGRect myRect = CGRectMake(sprite.position.x-spriteSize/2, sprite.position.y-spriteSize/2, spriteSize, spriteSize);


    if(CGRectContainsPoint(myRect, location)) {
        // particularSprite touched
        return kEventHandled;
    }
}
agfa555
A: 

I have been trying to figure out how to get hold of touches of a given sprite and found this thread.

Is this the correct way to detect which sprite was touched? This seems a rather odd way to do it compared to the usual sub-class way in obj-c?

So all the touch detection code is in the layer class?

Thanks for pointers

user7865437