Detect touch *anywhere on the screen* in cocos2d? - iphone

I'm really sorry, I realize there have been several questions asked about cocos2d touch detection (including this answer which helped me a bunch), but I just can't get any of them to work. I would have commented on the answer I linked instead of asking my own question, but i don't have enough rep to leave comments.
All I want to do is stop animation as soon as a user taps anywhere on the screen.
Here's my code so far:
- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"Touches Began");
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
location = [[Director sharedDirector] convertCoordinate: location];
CGRect mySurface = (CGRectMake(100, 100, 320, 480));
if(CGRectContainsPoint(mySurface, location)) {
NSLog(#"Event Handled");
return kEventHandled;
[[Director sharedDirector] stopAnimation];
}
return kEventIgnored;
NSLog(#"Event Ignored");
}
I've tried both BOOL and void, ccTouchesBegan and touchesBegan, in a layer file and a cocosNode file, and many other things. Nothing happens. Nothing shows in the log, and the animation continues on its merry little way. What am I doing wrong?

The main problem is that you've got the [[Director sharedDirector] stopAnimation]; after the return kEventHandled; rather than before it. return exits the function as soon as it's called, so anything after it will never get reached.
I don't have my mac in front of me to check the rest of your code, but it seems fine, so I'm guessing that's the main problem. If you're not even seeing the NSLog(#"Touches Began"); then you need to make sure that you're doing this in a CocosNode that extends Layer.
Another useful thing(once you're seeing the touches) is the NSStringFromCGPoint function, which allows you to easily display and debug the values in a CGPoint, so you could do something like:
NSLog(#"This layer was touched at %#", NSStringFromCGPoint(location));

Related

Cocos2d iPhone Game touch screen to make a character move

I have written a few games using cocos2d but they were all controlled by the accelerometer and used only simple touch events. All I need to do is register when the screen is touched, anywhere. I don't need any information about the position or velocity. The character currently moves across the screen and the users should be able to touch to make the character move up the screen. the current code does not work as intended. The character is not effected by the touch, it just continues to move down the screen. Please advise. Below is the code I am trying to use now.
In the game update method:
if (IsTouched == TRUE) {
SealPositionBasedOnTouchInt = SealPositionBasedOnTouchInt - (100*dt);
}
else {
SealPositionBasedOnTouchInt = SealPositionBasedOnTouchInt + (100*dt);
}
SealSwimming.position = ccp(SealPositionBasedOnTouchInt, SealSwimming.position.y);
The touch events:
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for( UITouch *touch in touches )
{
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
IsTouched = TRUE;
}
}
You'll notice I do get the touch location, this is currently not used for anything but was in the sample.
Make sure the layer has touch events enabled isTouchEnabled
Have you overridden:
-(void) registerWithTouchDispatcher {
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
in your layer/node that is receiving the touch?
You might also try and call from your code addTargetedDelegate:self without overriding registerWithTouchDispatcher, but I have never tried it.
Sergio has the answer to your problem with touches not registering. I had a similar problem recently. If it doesn't matter where the user touches the screen then swallowsTouches: YES is fine, but if you have a couple layers that need to register touches you might need to set it to NO.
I haven't tested this.
in .h
CCSprite *sprite;
in .m
-(id)init
{
if ((self=[super init))
{
CGSize s = [[CCDirector sharedDirector] winSize];
sprite = [CCSprite spriteWithFile:#"imagename.png"];
sprite.position = ccp(s.width/2, s.height/2);
[self addChild:sprite];
}
return self;
}
- (void) ccTouchesBegan: (NSSet *)touches withEvent: (UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
[sprite setPosition:touchLocation];
//OR YOU CAN RUN AN ANIMATION TO MAKE IT LOOK LIKE IT'S WALKING
//[sprite runAction:[CCMoveTo actionWithDuration:5 position:touchLocation]];
}

problem when drawing fast. Touching two point one after the another?

I created painting application...
Every thing drawing prefect..
Problem is when i running application in my mobile.
i am touching at point, and releasing the point... and touching another point and release another point.. while continuously doing same thing.
its get drawn line in between both point.
what to do?
Thanks in advance
If you do not record the inbetween points, your application will only create a line between the start and end. In order to get a line that curves to your tracing, you need to add an event for touchesMoved. Here is some psuedo-code of event handlers that is needed to create a drawing app.
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
//Record your first point here
CGPoint point = [ [touches anyObject] locationInView:self];
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
//Record another point
CGPoint point = [ [touches anyObject] locationInView:self];
//Call your rendering function
[self draw];
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//Record another point
CGPoint point = [ [touches anyObject] locationInView:self];
//Call your rendering function
[self draw]
//Add any finishing code here
}
Are you watching both touchesEnded and touchesCancelled?

How can I get touch co-ordinates in cocos2d?

What I want is that wherever user touches on iPhone screen, where I will display a pic at that place.
Can anyone help me how to get co-ordinates of the area everytime when user touches the screen?
You don't say you are using cocos2d, but you tagged your question as such. I will assume this is the case.
You need to put code in your ccTouchesEnded function. This is basically what it looks like:
-(BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
CCSprite *myImage = [CCSprite spriteWihFile: #"myImage.png"];
[myImage setPosition: location];
[self addChild: myImage];
return YES;
}
It sounds like you might need more help than that. If so, you should go to the cocos2d iphone page and look through the setup and tutorials.

How i can set an image to another fixed position by touch option?

I am trying to build an iPhone app by using Cocos2d. And i would like to set an image to another fixed position from a fixed position by using touch as my wish(speedy, or slowly). I have got some code but it does not work properly.
so friends it will more helpful to me if i get any solution.
The question is a little fuzzy, but if you want to set the position of a CocosNode you do:
[myNode setPosition:cpv(x,y)];
If you want the node to be offset from a touch location, you can do this by implementing ccTouchesBegan:withEvent
-(BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
CGPoint convertedLocation = [[Director sharedDirector] convertCoordinate:location];
[myNode setPosition: cpv(convertedLocation.x - 100, convertedLocation.y - 100)];
return kEventHandled;
}
That will offset the CocosNode by -100,-100 to where the touch occurred.
The ccTouchesBegan:withEvent: should be implemented in your Layer, and isTouchesEnabled should be set to YES to enable touches.

How can I detect touch in cocos2d?

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) ?
A better way to do this is to actually use the bounding box on the sprite itself (which is a CGRect). In this sample code, I put all my sprites in a NSMutableArray and I simple check if the sprite touch is in the bounding box. Make sure you turn on touch detection in the init. If you notice I also accept/reject touches on the layer by returning YES(if I use the touch) or NO(if I don't)
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint location = [self convertTouchToNodeSpace: touch];
for (CCSprite *station in _objectList)
{
if (CGRectContainsPoint(station.boundingBox, location))
{
DLog(#"Found sprite");
return YES;
}
}
return NO;
}
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
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.
}
#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;
}
}
#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.
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;
}
}
this is a good tutorial explaining the basic touch system
http://ganbarugames.com/2010/12/detecting-touch-events-in-cocos2d-iphone/
first, write
self.isTouchEnabled = YES;
then, you need to implement the functions ccTouchesEnded, ccTouchesBegan, etc
from what I understood, you want to be able to 'match' two sprites that can be on different coordinates on the screen.
a method for doing this.. : (im sure theres many other methods)
consider having 2 global variables.
so everytime a touch touches a sprite, you use the CGRectContainsPoint function that is mentioned several times to find which sprite has been touched. then, you can save the 'tag' of that sprite in one of the global variables.
You do the same for the second touch, and then you compare the 2 global variables.
you should be able to figure out the rest but comment if you have problems.