Hi,
Could you help me with the following task?
I have problem with collision detection of two sprite object.
A fast, easy to use, free, and community supported 2D game engine
Hi,
Could you help me with the following task?
I have problem with collision detection of two sprite object.
Are you using chipmunk/box2d?
Hey , Thanks for reply.
I am new to cocos2d framework and I am not implementing chipmunk to sprite object.
I have question that :
Is it necessary to use chipmunk to detect collision?
Is there no way to detect collision between two sprite object without chipmunk?
There are many ways to detect collisions. If you don't want to use chipmunk or box2d - then you can just do a CGRectContainsRect on the Rects of the objects. Check out
http://www.cocos2d-iphone.org/forum/topic/161#post-807 and http://www.cocos2d-iphone.org/forum/topic/200#post-1038 for some tips.
Or you could keep a list of the current positions of your sprites - and do a comparison of them every tick. Some sort of sorted array could do it.
But, if you want chipmunk to do all the work for you - then maybe read this post -
http://www.cocos2d-iphone.org/forum/topic/364
Justin
Yes, it is possible without Chipmunk. You could try creating a layer and use it to hold the 2 sprite objects. Then inside your game loop or tick, you can iterate through all the nodes in the layer and get their positions to check for collision.
jp could you please post the code?
I am in need of this aswell.
I used this code
[code]- (BOOL) rect:(CGRect) rect collisionWithRect:(CGRect) rectTwo
{
float rect_x1 = rect.origin.x;
float rect_x2 = rect_x1+rect.size.width;
float rect_y1 = rect.origin.y;
float rect_y2 = rect_y1+rect.size.height;
float rect2_x1 = rectTwo.origin.x;
float rect2_x2 = rect2_x1+rectTwo.size.width;
float rect2_y1 = rectTwo.origin.y;
float rect2_y2 = rect2_y1+rectTwo.size.height;
if((rect_x2 > rect2_x1 && rect_x1 < rect2_x2) &&(rect_y2 > rect2_y1 && rect_y1 < rect2_y2))
return YES;
return NO;
}[/code]
but I cannot get it to detect/go to MainScene after they collide
You could try something like this
Sprite *dog = [Sprite spriteWithFile:@"dog.png"];
Sprite *cat = [Sprite spriteWithFile:@"cat.png"];
Layer *animalLayer = [Layer node];
[animalLayer addChild:dog];
[animalLayer addChild:cat];
Then inside your game tick or loop
NSArray *animals = nil;
animals = [self.animalLayer children];
int numAnimals = [animals count];
Sprite *currentAnimal = nil;
for (int i = 0; i < numAnimals; i++) {
currentAnimal = [animals objectAtIndex:i];
float positionX = currentAnimal.position.x;
// do something with positionX, you can use your CGRects here
}
Sweet, but how would I implement this if I have two layers etc
I have MotionLayer (implements something falling)
and StickfigureLayer (stickfigure)
and I want to implement it into GameLayer
help would be much, much appreciated.
If StickFigureLayer and MotionLayer are visible in the GameLayer then you can iterate through the nodes of both layers inside GameLayer.
Now i'm confused, LOL.
I am a beginner-ish (amatuer) and I suck at coding, and I just need to do collision.
It would help if you could tell me how to do this in a beginner-ish way :)
Okay, well the way I see it - you could grab some info from my favourite blog article (the amount of times I post it, it must be my favourite!) - http://juanmunozar.blogspot.com/2009/02/cocos2d-iphone-dynamically-touch.html and create an array of the sprites that you want to detect collisions for. Then do as jp16 says above - and itinerate through it.
Steps to take:
in your game layer - add the following to the .h file:
+(NSMutableArray *)allMySprites;
add the following to he .m file after implementation:
static NSMutableArray * allMySprites = nil;
+(NSMutableArray *)allMySprites {
@synchronized(allMySprites) {
if (allMySprites == nil)
allMySprites = [[NSMutableArray alloc] init];
return allMySprites;
}
return nil;
}
Then when you create your sprites in your layers and add them - add them to the array also. Something like this might work (not testing any of this at the moment):
[[gameLayer allMySprites] addObject:aSprite];
Make sure that your sprites have some sort of rect function - or borrow the code from the rect functions on the above blog.
Now the modified collision detection code (using the rest of the code that jp16 gave you):
int count = [allMySprites count];
for (i = 0; i < count; i++) {
currentAnimal = [allMySprites objectAtIndex:i];
CGRect currentRect = [currentAnimal rect];
for (j = 0; j < count; j++) {
if (CGRectContainsRect(currentRect, [[allMySprites objectAtIndex:j] rect]) && j != i)
{
NSLog(@"We have a hit between %i and %i", i, j);
}
}
}
I think that would do it. Not doing it that way my self, I am using chipmunk - but would be interested to hear if that works well or not.
Justin
PS, the Rect function on that blog does not take into account any rotation on the object - which in the case of touch detection is not a big issue, but if you are using it for collision detection, then you might want to do some maths (or math if you like) and change the rect for each object taking into account the current rotation. If you only need a slightly better version then something along the lines of:
- (CGRect) rect {
float x = [self absolutePosition].x - [self contentSize].width/2;
float y = [self absolutePosition].y - [self contentSize].height/2;
float h = [self contentSize].height;
float w = [self contentSize].width;
if (self.rotation = 90 or self.rotation = 180)
{
// Rotation is 90 or 180 degrees - so reverse h and w
return CGRectMake(x,y,h,w);
}
else
return CGRectMake(x,y,w,h);
}
Obviously that is only correct if the object is fully rotated at 90 or 180 - so maybe you could give it a range. Or if you want to get fancy, you could constantly adjust the rect depending on rotation - or maybe have multiple rects per object.
So depending on the accuracy that you want - maybe you too should look at chipmunk or box2d for your collision detection! Or maybe don't compare rects at all - instead compare locations - if the difference between positions is less than a "threshold" then you have a hit.
Just thinking aloud.
If it's a simple rect intersection check. You can use CGRectIntersection which will return the intersection region of two overlaping rectangles.
Look into the api documentation for a better description
Hi!
Check this link
http://kwigbo.com/wp/?s=collision
The rectangles you would use in that function are the ones returned by your objects.
using for example their sprite's position and sizes.
Yeah, i'm using the rectangle to rectangle collision thing, but after they collide I want it to redirect to another scene, for example.
Well then you could have a flag in your game like objectsColliding = NO;
On every update check if they are colliding with the function you have, and if they are, set objectsColliding = YES.
Then also in the update function:
if(objectsColliding)
{
/*Code for changing scene, which i don't have at hand. Check the sceneTests, it is just 2 lines, first instantiate an scene object and then call a replaceScene*/
objectsColliding = NO
}Here's a little trick to improve the performance of the simple collision detection posted above:
int count = [allMySprites count];
for (i = 0; i < count; i++) {
currentAnimal = [allMySprites objectAtIndex:i];
CGRect currentRect = [currentAnimal rect];
for (j = i+1; j < count; j++) {
if (CGRectContainsRect(currentRect, [[allMySprites objectAtIndex:j] rect]))
{
NSLog(@"We have a hit between %i and %i", i, j);
}
}
}
The change is setting j = i + 1. The logic is that once you compare the sprite at index i with all the other sprites, you don't need to compare that sprite again. It has already been fully checked for all possible collisions. So set j = i + 1 in the inner loop to make it skip sprites that have already been fully checked.
For example, if you have 10 sprites indexed 0..9, then in the first iteration sprite 0 will get compared to sprites 1..9. In the second iteration, sprite 1 will get compared to sprites 2..9. There's no need to compare sprite 1 to sprite 0 again in the second iteration since you already did that in the first iteration.
That is a great point - should have picked that up.
Justin
I made a special method for determining (atlas) sprite bounding rectangles (wrapped into a "SpriteUtilities" class):
+(CGRect) positionRect: (AtlasSprite*)sprite {
CGSize contentSize = [sprite contentSize];
CGPoint contentPosition = [sprite position];
CGRect result = CGRectOffset(CGRectMake(0, 0, contentSize.width, contentSize.height), contentPosition.x-contentSize.width/2, contentPosition.y-contentSize.height/2);
return result;
}
Then to check for collision of two atlas sprites:
CGRect rect1 = [SpriteUtilities positionRect:atlasSprite1];
CGRect rect2 = [SpriteUtilities positionRect:atlasSprite2];
if (!CGRectIsNull(CGRectIntersection(rect1, rect2))) {
//handle collision
}Thanks for fallow up.
How to find collision of two sprite objects added on two different layer.
@pravin - if you are using an array of sprites it doesn't matter what layer they are on.
Look at my post about 10 up and then Cloudmike's post 4 up. That should do what you want.
Or use chipmunk, as per my post in this thread - http://www.cocos2d-iphone.org/forum/topic/364
Justin
where did the SpriteUtilities came from ? Where to declare it?
You must log in to post.