Undo with multitouch drawing in iOS - ios

I am working with multitouch while writing, So basically what I am doing is, I am writing with hand support, because typically, its how user rights, I followed this link How to ignore certain UITouch Points in multitouch sequence
Everything is working fine, but their is some problem with undo when I write with my hand touching the screen, otherwise it works fine.
Below is my code
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch* topmostTouch = self.trackingTouch;
for (UITouch *touch in touches)
{
ctr = 0;
touchStartPoint1 = [touch locationInView:self];
[m_undoArray removeAllObjects];
[m_redoArray removeAllObjects];
[m_parentRedoArray removeAllObjects];
if(!topmostTouch || [topmostTouch locationInView:self].y > touchStartPoint1.y)
{
topmostTouch = touch;
pts[0] = touchStartPoint1;
}
}
if (self.trackingTouch != nil && self.trackingTouch != topmostTouch) // ![touches containsObject:self.trackingTouch])
{
[self discardDrawing];
}
self.trackingTouch = topmostTouch;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if(self.trackingTouch== nil)
{
return;
}
CGPoint p = [self.trackingTouch locationInView:self];
ctr++;
pts[ctr] = p;
if (ctr == 4)
{
pts[3] = midPoint(pts[2], pts[4]);
self.currentPath = [[DrawingPath alloc] init];
[self.currentPath setPathColor:self.lineColor];
self.currentPath.pathWidth = [NSString stringWithFormat:#"%f",self.lineWidth];
[self.currentPath.path moveToPoint:pts[0]];
[self.currentPath.path addCurveToPoint:pts[3] controlPoint1:pts[1] controlPoint2:pts[2]];
CGPathRef cgPath = self.currentPath.path.CGPath;
mutablePath = CGPathCreateMutableCopy(cgPath);
[m_undoArray addObject:self.currentPath];
[self setNeedsDisplay];
pts[0] = pts[3];
pts[1] = pts[4];
ctr = 1;
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches)
{
if(touch == self.trackingTouch)
{
[m_parentUndoArray addObject:[NSArray arrayWithArray:m_undoArray]];
}
}
}
-(void)undoButtonClicked
{
NSMutableArray *undoArray = [m_parentUndoArray lastObject];
NSLog(#"%#",undoArray);
[m_parentUndoArray removeLastObject];
[m_parentRedoArray addObject:undoArray];
m_drawStep = UNDO;
[self setNeedsDisplay];
}
- (void)drawRect
{
I have different cases here, I am showing Of Undo
for(int i = 0; i<[m_parentUndoArray count];i++)
{
NSMutableArray *undoArray = [m_parentUndoArray objectAtIndex:i];
NSLog(#"%#",undoArray);
for(int i =0; i<[undoArray count];i++)
{
DrawingPath *drawPath = [undoArray objectAtIndex:i];
GPathRef path = drawPath.path.CGPath;
mutablePath = CGPathCreateMutableCopy(path);
//Draw into CgLayer
}
}
}
Here is the image to understand my problem better, I first wrote this
After clicking on Undo once,you can see above that, some other part has been undone, instead of the last part. So I need you help in this regard.

m_redoArray appears to be the big daddy, the one you draw from. I don't understand why you empty this out out in 'touchesBegan...', surely one of these arrays must carry through touchesBegan unaltered, or you'll be dropping stuff from the start of your drawing all the way through, no?
It appears to me that this is how you dropped the 'Hell' in your example here..

Well in my case i have used bezierPath to draw on touch and have successfully implemented undo functionality. Here is the code :
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor = [UIColor clearColor];
myPath = [[UIBezierPath alloc] init];
myPath.lineCapStyle = kCGLineCapRound;
myPath.miterLimit = 0;
bSize=5;
myPath.lineWidth = bSize;
brushPattern = [UIColor whiteColor];
// Arrays for saving undo-redo steps in arrays
pathArray = [[NSMutableArray alloc] init];
bufferArray = [[NSMutableArray alloc] init];
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
[brushPattern setStroke];
for (id path in pathArray){
if ([path isKindOfClass:[UIBezierPath class]]) {
UIBezierPath *_path=(UIBezierPath *)path;
[_path strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
}
}
}
#pragma mark - Touch Methods
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *mytouch = [[touches allObjects] objectAtIndex:0];
myPath = [[UIBezierPath alloc] init];
myPath.lineWidth = bSize;
[myPath moveToPoint:[mytouch locationInView:self]];
[pathArray addObject:myPath];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[myPath addLineToPoint:[[touches anyObject] locationInView:self]];
[self setNeedsDisplay];
}
#pragma mark - Undo Method
-(void)undoButtonClicked
{
if([pathArray count]>0)
{
UIBezierPath *_path = [pathArray lastObject];
[bufferArray addObject:_path];
[pathArray removeLastObject];
[self setNeedsDisplay];
}
}
-(void)setBrushSize: (CGFloat)brushSize
{
bSize=brushSize;
}
-(void)redoButtonClicked
{
if([bufferArray count]>0){
UIBezierPath *_path = [bufferArray lastObject];
[pathArray addObject:_path];
[bufferArray removeLastObject];
[self setNeedsDisplay];
}
}
Hope it will help you.

Related

How will i remove UIBezierPath from the uiview on button click.?

I am working on digital signature on uiview. i create it normaly by this code, but i am not able to remove bezier path on button click.i am sharing my code PLease look at my code.
#import "Signature.h"
#implementation Signature {
UIBezierPath *path;
UIImage *incrementalImage;
CGPoint pts[5]; // we now need to keep track of the four points of a Bezier segment and the first control point of the next segment
uint ctr;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder])
{
[self setMultipleTouchEnabled:NO];
[self setBackgroundColor:[UIColor greenColor]];
path = [UIBezierPath bezierPath];
[path setLineWidth:2.0];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setMultipleTouchEnabled:NO];
path = [UIBezierPath bezierPath];
[path setLineWidth:2.0];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
[incrementalImage drawInRect:rect];
[path stroke];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
ctr = 0;
UITouch *touch = [touches anyObject];
pts[0] = [touch locationInView:self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
ctr++;
pts[ctr] = p;
if (ctr == 4)
{
pts[3] = CGPointMake((pts[2].x + pts[4].x)/2.0, (pts[2].y + pts[4].y)/2.0); // move the endpoint to the middle of the line joining the second control point of the first Bezier segment and the first control point of the second Bezier segment
[path moveToPoint:pts[0]];
[path addCurveToPoint:pts[3] controlPoint1:pts[1] controlPoint2:pts[2]]; // add a cubic Bezier from pt[0] to pt[3], with control points pt[1] and pt[2]
[self setNeedsDisplay];
// replace points and get ready to handle the next segment
pts[0] = pts[3];
pts[1] = pts[4];
ctr = 1;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self drawBitmap];
[self setNeedsDisplay];
[path removeAllPoints];
ctr = 0;
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"hello");
[self touchesEnded:touches withEvent:event];
}
- (void)drawBitmap
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0);
if (!incrementalImage) // first time; paint background white
{
UIBezierPath *rectpath = [UIBezierPath bezierPathWithRect:self.bounds];
[[UIColor greenColor] setFill];
[rectpath fill];
}
[incrementalImage drawAtPoint:CGPointZero];
[[UIColor blackColor] setStroke];
[path stroke];
incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
- (void)erase {
NSLog(#"Erase Testing...");
// self->path = nil; //Set current path nil
//path = [UIBezierPath bezierPath];
// [self setNeedsDisplay];
}
I call erase method on unbutton click from another class, but I am not able to remove uibezeripath.
Try using this to remove the UIBezierPath,
[path removeAllPoints];
If you use CAShapeLayer *rectLayer = [[CAShapeLayer alloc] init]; aswell then call this line too,
[rectLayer removeFromSuperlayer];
Check how i am using this in one of my project if it can help,
- (void)drawRect:(CGRect)rect {
[_path stroke];
}
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame: frame];
if (self) {
// set Multiple touches Enabled to false for allow only single touch.
[self setMultipleTouchEnabled: NO];
_path = [UIBezierPath bezierPath];
// set Line width.
[_path setLineWidth:2.0];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
isMouseswipped = NO; //for touches eneded to make dot
ctr = 0;
UITouch *myTouch = [touches anyObject];
pts[0] = [myTouch locationInView: self];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
isMouseswipped = YES; //for touches eneded to make dot
CustomSignatureViewController *csvc = [[CustomSignatureViewController alloc]init];
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView: self];
ctr++;
pts[ctr] = p;
if (ctr == 4) {
pts[3] = CGPointMake((pts[2].x + pts[4].x)/2.0, (pts[2].y + pts[4].y)/2.0);
[_path moveToPoint: pts[0]];
[_path addCurveToPoint: pts[3] controlPoint1:pts[1] controlPoint2:pts[2]];
[self setNeedsDisplay];
pts[0] = pts[3];
pts[1] = pts[4];
ctr = 1;
csvc.status = 1;
self.status = 1;
}
}
- (void)erase {
_path = nil;
_path = [UIBezierPath bezierPath];
[_path setLineWidth:2.0];
[self setNeedsDisplay];
}
This is custom class which returns uiview to fraw signature. It is subclass of UIView.
So when required signature, i import this class and instantiate it and got uiview object on which i can draw. then capture that view as image using graphics beginimage context!
Update :
In viewcontroller i am calling method like,
-(void)clear : (id)sender{
[signView erase];
signView.status = 0;
}
signView is signature class(as mentioned above)'s object. and erase is public method declared in .h file of signature class. (note : signature class is subclass of uiview so intance of it returns view onject so signView is uiview object)
Hope this will help :)
use this code it will help you
- (void)resetPath {
path = nil;
path = [UIBezierPath bezierPath];
[self setNeedsDisplay];
}
create this method in .h file of your subclass. From your UIViewController class you call this method whenever you need it
- (IBAction)youraction:(id)sender
{
[self.subclassedView resetPath];
}

Spritekit - Using gestures to draw multiple lines with multiple fingers simultaneously

Using the below code, I can draw a line using the pan gesture using 1 finger. However what I am attempting to do is for 1 finger to draw 1 line and another finger to draw the second simultaneously. I've read somewhere about using a dictionary to store the touches but don't know how to write it in code. Can any one help?
-(void)didMoveToView:(SKView *)view {
UIPanGestureRecognizer *gestureRecognizerPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanFrom:)];
[[self view] addGestureRecognizer:gestureRecognizerPan];
}
- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateBegan) {
CGPoint touchLocation = [recognizer locationInView:recognizer.view];
touchLocation = [self convertPointFromView:touchLocation];
pathToDraw = CGPathCreateMutable();
CGPathMoveToPoint(pathToDraw, NULL, touchLocation.x, touchLocation.y);
lineNode = [[SKShapeNode alloc] init];
lineNode.path = pathToDraw;
lineNode.name = lineNodeCategoryName;
[_gameLineNode addChild:lineNode];
} else if (recognizer.state == UIGestureRecognizerStateChanged) {
CGPoint touchLocation = [recognizer locationInView:recognizer.view];
touchLocation = [self convertPointFromView:touchLocation];
CGPathAddLineToPoint(pathToDraw, NULL, touchLocation.x, touchLocation.y);
lineNode.path = pathToDraw;
lineNode.name = lineNodeCategoryName;
lineNode.physicsBody = [SKPhysicsBody bodyWithEdgeChainFromPath:pathToDraw];
lineNode.physicsBody.dynamic = YES;
lineNode.strokeColor = [SKColor blackColor];
lineNode.glowWidth = 3.0;
} else if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPathRelease(pathToDraw);
}
}
Drawing multiple lines simultaneously is fairly straightforward. The key is to track each touch event independently. One way to do that is to maintain a dictionary that uses the touch event as the key and the shape node (used to draw the line) as the value.
#implementation GameScene {
NSMutableDictionary *lines;
}
-(void)didMoveToView:(SKView *)view {
self.scaleMode = SKSceneScaleModeResizeFill;
// Create a mutable dictionary
lines = [NSMutableDictionary dictionaryWithCapacity:10];
}
// Add each line node to the dictionary with the touch event as the key
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
// Create a mutable path
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:location];
// Create a shape node using the path
SKShapeNode *lineNode = [SKShapeNode shapeNodeWithPath:path.CGPath];
lineNode.strokeColor = [SKColor blackColor];
[self addChild:lineNode];
// Use touch pointer as the dictionary key. Since the dictionary key must conform to
// NSCopying, box the touch pointer in an NSValue
NSValue *key = [NSValue valueWithPointer:(void *)touch];
[lines setObject:lineNode forKey:key];
}
}
// Update the lines as needed
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
// Retrieve the shape node that corresponds to touch
NSValue *key = [NSValue valueWithPointer:(void *)touch];
SKShapeNode *lineNode = [lines objectForKey:key];
if (lineNode != NULL) {
// Create and initialize a mutable path with the lineNode's current path
UIBezierPath *path = [UIBezierPath bezierPathWithCGPath:lineNode.path];
// Add a line to the current touch point
[path addLineToPoint:location];
// Update lineNode
lineNode.path = path.CGPath;
}
}
}
// Remove the line nodes from the dictionary when the touch ends
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
NSValue *key = [NSValue valueWithPointer:(void *)touch];
[lines removeObjectForKey:key];
}
}
#end

Objective-c: ccTouchesBegin End and Moved not Firing when using Custom Sprites

I have a Ship Class, in this Ship Class i have the methods ccTouchesBegin, ccTouchesEnd and ccTouchesMoved. But these methods never fire:
Here is the Ship Class:
//
// Ship.m
// Asteroids
//
// Created by trikam patel on 06/08/2014.
// Copyright 2014 trikam patel. All rights reserved.
//
#import "Ship.h"
#import "Helper.h"
#implementation Ship
// on "init" you need to initialize your instance
-(id)init:(NSString*)imageName :(NSMutableArray*)asteroids
{
if( (self=[super init:imageName]) ) {
asteroids = asteroids;
}
return self;
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
for(UITouch *t in touches){
CGPoint point = [self convertTouchToNodeSpace:t];
if(allowedToMove){
if(hasShipHit){
if(!shiphit){
shiphit = [[CCSprite alloc] init];
CCSpriteBatchNode *spritesheet = [Helper setupAnimation:#"shiphit" :2 :shiphit];
[self addChild:spritesheet];
}
[shiphit setPosition:ccp([self position].x, [self position].y)];
[shiphit setPosition:ccp(point.x, point.y + 76)];
}else{
[self setPosition:ccp(point.x, point.y + 76)];
}
}
}
}
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
for(UITouch *t in touches){
CGPoint point = [self convertTouchToNodeSpace:t];
NSLog(#"begin move ship");
if(hasShipHit){
int shipX = [shiphit position].x;
int shipY = [shiphit position].y;
if (CGRectContainsPoint(CGRectMake (shipX - 20.5, shipY - 96, 50, 50), point))
{
allowedToMove = true;
}
}else{
int shipX = [self position].x;
int shipY = [self position].y;
if (CGRectContainsPoint(CGRectMake (shipX - 20.5, shipY - 96, 50, 50), point))
{
allowedToMove = true;
}
}
}
}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
for(UITouch *t in touches){
CGPoint point = [self convertTouchToNodeSpace:t];
allowedToMove = false;
}
}
This is how the Ship Class gets used in the Parent:
self.isTouchEnabled = YES;
Background *backgorund = [[Background alloc] init:#"bg1.png"];
[self addChild:backgorund];
ship = [[Ship alloc] init:#"ship.png" :asteroidArray];
[ship setPosition:ccp(100, 100)];
[self addChild:ship];
Your ship class must enable touch processing so it respond to Touch methods such as TouchesBegan and TouchesEnded. If I got it correct, your Ship class is a custom CCSprite or something similar, so probably it won't have any isTouchEnabled property.
Use your touches methods in your Parent Layer and call your ship methods from there.
Something like...
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
for(UITouch *t in touches){
CGPoint point = [self convertTouchToNodeSpace:t];
[ship methodForTouch:point];
}
}
Hope it helps :)

Detect objects, touchesmoved and UITouch

I have a UIView on where i add balls with a ID. When i touch the ball with the ID 1 i draw a dashed line follows my finger.
The problem if when i move the finger to the other balls, i don't know how to detect these balls and check the ID they have. The what i need to happen is when i touch the next ball with the ID 2, the line finish draw and stay from ball 1 to ball 2, and create new one from 2 to finger, next.. 3 etc...
The code:
#import "DrawView.h"
#implementation DrawView
- (id)init
{
self = [super initWithFrame:CGRectMake(0, 0, 1024, 768)];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.opaque = YES;
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:315 posY:138 andNumber:1];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:706 posY:138 andNumber:2];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:315 posY:526 andNumber:3];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:706 posY:526 andNumber:4];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
}
return self;
}
- (Line *)drawLine {
return drawLine;
}
- (void)setDrawLine:(Line *)line
{
drawLine = line;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CheckPointCircle * checkTouch = (CheckPointCircle *)touch.view;
if (touch.view.class == checkPointCircle.class) {
if ([checkTouch getObjectID] == 1) {
startTouchPoint = CGPointMake([checkTouch center].x, [checkTouch center].y);
endTouchPoint = [touch locationInView:self];
}
}
self.drawLine = [[Line alloc] initWithPoint:[touch locationInView:self]];
[self setNeedsDisplay];
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"Cancelado");
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
UITouch *secondaryTouch = (UITouch *)[[[event touchesForView:checkPointCircle] allObjects] objectAtIndex: 0];
NSLog(#"Que toco: %# ", secondaryTouch.view);
if (touch.view.class == checkPointCircle.class) {
CheckPointCircle * checkTouch = (CheckPointCircle *)touch.view;
if ([checkTouch getObjectID] == 1) {
endTouchPoint = [touch locationInView:self];
}
}
[self setNeedsDisplay];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CheckPointCircle * checkTouch = (CheckPointCircle *)touch.view;
if (touch.view.class == checkPointCircle.class) {
if ([checkTouch getObjectID] == 1) {
endTouchPoint = [touch locationInView:self];
}
}
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
[drawLine drawLineFrom:startTouchPoint to:endTouchPoint];
}
#end
How to detect the other balls to get the ID.
Can anybody help me?
Thanks!
The Apple documentation of class UIView (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/hitTest:withEvent:) lists two methods which will determine which view contains a hit/point:
– hitTest:withEvent:
– pointInside:withEvent:
Probably hitTest will help most: Its description reads "Returns the farthest descendant of the receiver in the view hierarchy (including itself) that contains a specified point.", so it even converts coordinates as needed.
If you check [self hitTest: [touch.locationInView self] withEvent: event] (or similar, no code completion here ;-)= in your touchesMoved: method, you should be able to detect when the finger is over any of the other circles.
Hope this helps, nobi

CGRect and touch

In this cocos2d app the nslog is not firing when I press the ccsprite. Could someone help me?
-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{
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),
27,
40);
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
if (CGRectContainsPoint(targetRect, touchLocation)) {
NSLog(#"Moo cheese!");
}
}
return YES;
}
First of all be sure that you register the sprite for touches into the onEnter method for example:
- (void)onEnter
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:defaultTouchPriority_ swallowsTouches:YES];
[super onEnter];
}
This will make your sprite touchable and so fire the event to the sprite when a user will press it.
Then refactor your code to make it more readable and test something like that:
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
NSArray *targetsToDelete = [self touchedSpritesAtLocation:touchLocation];
// Put your code here
// ...
return YES;
}
- (NSArray *)touchedSpritesAtLocation:(CGPoint)location
{
NSMutableArray *touchedSprites = [[NSMutableArray alloc] init];
for (CCSprite *target in _targets)
if (CGRectContainsPoint(target.boundingBox, location))
[touchedSprites addObject:target];
return [touchedSprites autorelease];
}
It should return the targets that have been touched.
In layer init method add this
self.isTouchEnabled = true;
Use this code for touch detection
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CGRect rect = [self getSpriteRect:yourSprite];
if (CGRectContainsPoint(rect, location))
{
NSLog(#"Sprite touched\n");
}
}
To get sprite rect:
-(CGRect)getSpriteRect:(CCNode *)inSprite
{
CGRect sprRect = CGRectMake(
inSprite.position.x - inSprite.contentSize.width*inSprite.anchorPoint.x,
inSprite.position.y - inSprite.contentSize.height*inSprite.anchorPoint.y,
inSprite.contentSize.width,
inSprite.contentSize.height
);
return sprRect;
}

Resources