Looping through an array to remove a touched object (iPhone/Cocos2d) - iphone

I am using cocos2d to build a game. I have an array of CCSprites and I want to be able to touch them and delete the one that was touched.
Right now I have this...
-(void) spawn {
mySprite = [CCSprite spriteWithFile:#"image.png"];
mySprite.position = ccp(positionX,positionY);
[myArray addObject:mySprite];
[self addChild:mySprite];
}
- (void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
NSUInteger i, count = [myArray count];
for (i = 0; i < count; i++) {
mySprite = (CCSprite *)[myArray objectAtIndex:i];
if (CGRectContainsPoint([mySprite boundingBox], location)) {
[self removeChild:mySprite cleanup:YES];
}
}
I have never done this before. Does anyone have a solution?
Thanks,
Michael

- (void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
NSMutableArray *spritesToDelete = [[NSMutableArray alloc] init];
for(CCSprite* mySprite in myArray) {
if (CGRectContainsPoint([mySprite boundingBox], location))
[spritesToDelete addObject:mySprite];
for(CCSprite* deadSprite in spritesToDelete) {
[self removeChild:deadSprite cleanup:YES];
[myArray removeObject:deadSprite];
}
}
This code uses a for-each to create an array of the objects that meet your condition, and then removes them.

Related

Wrong sprite moving when touched

I have 20 sprites in my scene which I've added to a NSMutableArray. My problem is that when I drag one sprite over another, the other also moves. How do I restrict the movement of untouched sprites?
Please help me with code (I am new to Cocos2d).
if( (self=[super init])) {
collection=[[NSMutableArray alloc]init];
CCLayer *base=[CCSprite spriteWithFile:#"Base.png"];
base.position=ccp(512,384);
[self addChild:base];
x=0;
for(int i=1;i<=7;i++)
{
CCSprite *hole=[CCSprite spriteWithFile:#"ball.png"];
hole.position=ccp(140+x,318);
hole.tag=i;
[self addChild:hole];
hole.visible=YES;
[collection addObject:hole];
x=x+75;
}
self.isTouchEnabled=YES;
}
return self;
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"count:%i",[collection count]);
UITouch *touch=[touches anyObject];
CGPoint location=[touch locationInView:[touch view]];
location=[[CCDirector sharedDirector]convertToGL:location];
location=[self convertToNodeSpace:location];
for(CCSprite *s in collection)
{
if(CGRectContainsPoint([s boundingBox], location))
s.position=ccp(location.x,location.y);
return;
}
}
You can do that:
Declare this in interface .h file
CCSprite *mSpriteOnHand;
CGPoint mLastPos;
Inside init assign it to nil.
mSpriteOnHand = nil;
In touchesBegan method check like this
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
for(CCSprite *s in collection)
{
if(CGRectContainsPoint([s boundingBox], location))
{
mLastPos = s.position;
s.position=ccp(location.x,location.y);
mSpriteOnHand = s;
break;
}
}
}
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[touches anyObject];
CGPoint location=[touch locationInView:[touch view]];
location=[[CCDirector sharedDirector]convertToGL:location];
location=[self convertToNodeSpace:location];
if(mSpriteOnHand)
{
mSpriteOnHand.position = location;
}
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if(mSpriteOnHand)
{
mSpriteOnHand.position = mLastPos;
mSpriteOnHand = nil;
}
}

Iphone Detect each Fingers and Draw Line (Using cocos2d/openGL for Drawing)

I understand the basics of how multi-touch Event works
When a figer touches the view/screen that view will receive ccTouchesBegan with a set of UITouch.
UITouch will hold the location (CGPoint) and its unique for each finger.
If more than one finger touches the view at the same time , 2 UITouch will be send to the view.
Sometime view will receive ccTouchesBegan with 2 UITouch's or ccTouchesBegan will be called twise for each finger touch one after another.
If finger1 is moving view will receive ccTouchesMoved with one UITouch.
My question is how to draw lines with each finger touch seperately , put the 1 or 2 fingers on the screen and draw line for each finger touch began/moved/end?
The below code works when there is only single touch but for multi touch it wont work because of the above point 3 and 4.
Exactly like this
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] > 0) {
// handle multi touch
UITouch *touch1 = [[touches allObjects] objectAtIndex:0];
CGPoint touchLocation1 = [touch1 locationInView: [touch1 view]];
touchLocation1 = [[CCDirector sharedDirector] convertToGL: touchLocation1];
Edge *temEdge1 = (Edge*)[temEdges objectAtIndex:0];
[[temEdge1 end] updateXY:touchLocation1];
[[temEdge1 start] updateXY:touchLocation1];
if ([touches count] > 1) {
UITouch *touch2 = [[touches allObjects] objectAtIndex:1];
CGPoint touchLocation2 = [touch2 locationInView: [touch2 view]];
touchLocation2 = [[CCDirector sharedDirector] convertToGL: touchLocation2];
Edge *temEdge2 = (Edge*)[temEdges objectAtIndex:1];
[[temEdge2 end] updateXY:touchLocation2];
[[temEdge2 start] updateXY:touchLocation2];
}
}
}
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] > 0) {
// handle multi touch
UITouch *touch1 = [[touches allObjects] objectAtIndex:0];
CGPoint touchLocation1 = [touch1 locationInView: [touch1 view]];
touchLocation1 = [[CCDirector sharedDirector] convertToGL: touchLocation1];
Edge *temEdge1 = (Edge*)[temEdges objectAtIndex:0];
[[temEdge1 end] updateXY:touchLocation1];
if ([touches count] > 1) {
UITouch *touch2 = [[touches allObjects] objectAtIndex:1];
CGPoint touchLocation2 = [touch2 locationInView: [touch2 view]];
touchLocation2 = [[CCDirector sharedDirector] convertToGL: touchLocation2];
Edge *temEdge2 = (Edge*)[temEdges objectAtIndex:1];
[[temEdge2 end] updateXY:touchLocation2];
}
}
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] > 0) {
// handle multi touch
UITouch *touch1 = [[touches allObjects] objectAtIndex:0];
CGPoint touchLocation1 = [touch1 locationInView: [touch1 view]];
touchLocation1 = [[CCDirector sharedDirector] convertToGL: touchLocation1];
Edge *temEdge1 = (Edge*)[temEdges objectAtIndex:0];
[[temEdge1 end] updateXY:touchLocation1];
if ([touches count] > 1) {
UITouch *touch2 = [[touches allObjects] objectAtIndex:1];
CGPoint touchLocation2 = [touch2 locationInView: [touch2 view]];
touchLocation2 = [[CCDirector sharedDirector] convertToGL: touchLocation2];
Edge *temEdge2 = (Edge*)[temEdges objectAtIndex:1];
[[temEdge2 end] updateXY:touchLocation2];
}
}
}
-(void)draw
{
[super draw];
glLineWidth(5.f);
ccDrawColor4B(0, 0, 255, 255);
for (Edge *temEdge in temEdges) {
CGPoint start = [[temEdge start] toCCP];
CGPoint end = [[temEdge end] toCCP];
ccDrawLine(start , end);
}
}
You can try to associate arrays of touch positions with different touches(something like NSDictionary with UITouches as keys and NSArrays of points as values). Then you can draw these lines using ccDrawLine or any other way if your draw method. Just do not forget to store these arrays somwhere where current touch ends.

how to store CGPoint in array

Hi I am trying to store the move points in the NSMutableArray so I have tries like this
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *move = [[event allTouches] anyObject];
CGPoint MovePoint = [move locationInView:self.view];
if (MovePointsArray==NULL) {
MovePointsArray=[[NSMutableArray alloc]init];
}
[MovePointsArray arrayWithObjects:[NSValue valueWithCGPoint:MovePoint]];
}
but this doesn't work how can i store these points in NSMutableArray
You should use addObject: in the last line:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *move = [[event allTouches] anyObject];
CGPoint MovePoint = [move locationInView:self.view];
if (MovePointsArray==NULL) {
MovePointsArray=[[NSMutableArray alloc]init];
}
[MovePointsArray addObject:[NSValue valueWithCGPoint:MovePoint]];
}
You should do like this :
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *move = [[event allTouches] anyObject];
CGPoint MovePoint = [move locationInView:self.view];
if (MovePointsArray == NULL) {
MovePointsArray = [[NSMutableArray arrayWithObjects:[NSValue valueWithCGPoint:MovePoint, nil];
}
else {
[MovePointsArray addObject:[NSValue valueWithCGPoint:MovePoint]];
}
}
don't forget to retain / relase the array as you don't see to use a property accessor.
Best, you should alloc/init the array in your init method and then only do here :
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *move = [[event allTouches] anyObject];
CGPoint MovePoint = [move locationInView:self.view];
[MovePointsArray addObject:[NSValue valueWithCGPoint:MovePoint]];
}
If you want to get an array using method arrayWithObjects you must also add nil as the last element of the array.
like so:
[MovePointsArray arrayWithObjects:[NSValue valueWithCGPoint:MovePoint], nil];
but to add an object to an existing array you should use addObject method
[MovePointsArray addObject:[NSValue valueWithCGPoint:MovePoint]];

Multi-touch co-ordinates problem iPhone

I am trying to find the coordinates of both touches in a multi touch. This code throws a SIGABRT on the line 'UITouch *touch2 = ...'. could anyone please tell me where I'm going wrong?
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSArray *touchArray = [touches allObjects];
UITouch *touch1 = [touchArray objectAtIndex:0];
UITouch *touch2 = [touchArray objectAtIndex:1];
CGPoint firstTouch = [touch1 locationInView:self.view];
CGPoint secondTouch = [touch2 locationInView:self.view];
}
Most likely there is only one touch in the array. You should check that the array contains an index before you try to retrieve the object at that index:
NSUInteger count = [array count];
id obj = (count > 1)? [array objectAtIndex:1] : nil;
id obj2 = (count > 2)? [array objectAtIndex:2] : nil;
If you want to get a double click event, you need to check the value of tapCount of each UITouch object instead of whether touches has two objects.
for (UITouch *touch in touches) {
if (touch.tapCount==1) {
// do something
} else if (touch.tapCount==2) {
// do something else
}
}

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