I've got a player sprite that I can move around on the screen using the accelerometer. Now I want to check if it collides with any of the many randomly falling objects I've created. I know about the CGRectIntersectsRect function, but I don't want to have to know the other object's name. Is there some kind of getElementAt function like in Java, that I can continue to check if there is any object overlapping with my player?
Thanks in advance!
The only cocos2d equivalent to getElementAt I know of is getChildByTag:. Alternatively You can loop through every child of the layer using:
for (CCNode *child in [self children]) {
if (CGRectIntersects(child.boundingBox, player.boundingBox) {
// perform collision stuff
}
}
Also important to remember is that this is horribly inefficient, particularly with many objects. You might consider using a physics engine to perform the efficient collision detection for you.
Related
I have a sphere build from multiple objects. What I want to do is when I touch/click an object, that object should find all adjunctive objects. But because none off them are moving, no collision detection can be used.
I can't find a way to detect these adjunctive objects even when the colliders do collide with each other, as I can see that in the scene. I tried all the possibilities, but none off them are working, because no objects are moving.
Is there a way to check for manual collision detection, or is there some sort of way to let Unity3d do the collision detection automatically?
You could keep a list of all those objects, then when your event happens you can send messages to all them to do what you want them to do.
Lets assume you want your sphere to break into little pieces. You send a Force message to the sphere. Then you use Newton's Laws of motion and find out how much velocity each piece gets. Remember velocity is a vector thus it has direction.
This is how I would do it and still keep the right amount of control over what happens in my game/simulation. Remember F = ma.
you could use RaycastHit (http://docs.unity3d.com/Documentation/ScriptReference/RaycastHit.html) for your collision, this also works on non-moving objects but it needs more performance
You can add rigidbody to every objects; when you touch one of them, give a force onto it, then it is going to move and trigger event of the adjacent objects.
for the reason you do not want to move the object you touch, you can cancel movement in the OnCollider or OnTrigger event handler function.
I managed to work around this by checking the distance from the selected object and all other objects that are part of the sphere. If the distance is below a certain value, then it is an adjunctive object.
Although this is certaintly not fool proof, it works without problems so far.
I am sorry I was not clear enough. Thanks for all the advice what so ever.
I am making a game in Cocos2d. I have enemies that shoot, and have the character shoot. I created a separate layer for the enemies (and their bullets) and a separate layer for the character (and its bullets). The problem is, I don't know how to detect collisions between the two layers. Note, I have the Scene in HelloWorldLayer, and each of the above layers is a child of the scene. Any help is appreciated. Thanks!
You need to add following lines if your using chipmunks
shape->collision_type = kCollisionTypeParticle;
cpSpaceAddCollisionHandler(space_,
kCollisionTypeParticle,
kCollisionTypeParticle,
collisonDetect,
NULL,
NULL,
NULL,
self);
Here collisonDetect is a method we need to register as:
cpBool collisonDetect(cpArbiter *arb, struct cpSpace *space, void *data)
{
<YOUR CLASS> *layer = (<YOUR CLASS> *)data;
[layer collisonDetect:arb];
return cpTrue;
}
Now here here you will handle rest of the code
-(void)collisonDetect:(cpArbiter*)arb
{
NSLog(#"COLLISION DETECTED");
}
You can detect collision in Cocos2D using CGRectIntersectsRect.
Your idea regarding creation of separate layers for enemies and bullets might prove to be confusing. In this scenario you should consider going for one layer. You must have had a look on Ray Wenderlich of collision detection. If not have a look at Simple Cocos2d game.
If you require more help, let me know.
Why not create the bullets on the opposite layer from the bullet source, i.e. layer A is the character and the enemy bullets, layer B is the enemy and the character bullets? Then your collision detection would be on the same layer.
Look into CGRectIntersectsRect.... I haven't done Cocos2D in a LONG time but I do remember using a Scheduler to regularly invoke a method which would detect collisions using the CGRectIntersectsRect method...
I had a limited number of sprites on screen and on every pass of the collision detection method I would check to see if any of my enemy sprite frames intersected with my protagonist's frames using CGRectIntersectsRect.
This is how I did it:
Step 1:
Implement a method that uses CGRectIntersectsRect to check if the the sprite frames are touching. It could look something like:
- (BOOL)detectCollision
{
CGRect frame1 = someframe;
CGRect frame2 = anotherframe;
if(CGRectIntersectsRect(frame1, frame2))
return YES;
else
return NO;
}
Implement a Scheduler to invoke your collision detection method every seconds using:
[self schedule: #selector(detectCollision) interval:0.25];
This way in your game everytime the collisionDetect method is called you can detect collisions. :)
I am new to Objective-C. I am currently working on a game using Cocos2D and Box2D. My problem is that when 3 objects collide together, the game crashes. Now let me describe my game in details:
In my game I have a main character standing on top of a building. Below the building there's this the road. Enemies pass by the road at various random speeds entering the screen from right and exiting from the left. I have created the enemies as b2_kinematicBodies and set a random velocity for each of them using SetLinearVelocity(). The main character shoots the enemies. The projectile (the object being shot) is a b2_dynamicBody. When the projectile hits the enemies, both the projectile and the enemy are destroyed. During gameplay sometimes an enemy moving at a slow speed is crossed by one which is moving at a higher speed. If a projectile hits the two enemies just at the point when they are overlapping and one is about to pass the other one, the game crashes! Please help me with this.
I have detected collision using b2contactListener class.
One thing I didn't mention before is that I am not creating the enemies as individual distinct bodies. Instead, I am creating it once and making it move and I am calling this method (which creates the enemies and makes them move) inside init as below:
[self schedule:#selector(addRightTarget) interval:2.0];
I believe the issue is that the collisions are calculated before your handler gets any calls. Meaning that when your handler gets called, the bullet has hit 2 objects. So you get 2 call-backs as shown below.
Collision Detected: Bullet + Enemy1
Destroy Enemy1
Destroy Bullet
Collision Detected: Bullet + Enemy2
Destroy Enemy2
Destroy Bullet [CRAAAASH!!! You just tried to delete a non-existent object]
1st: You should not be removing anything except in your step function (as someone mentioned in another answer)
2nd: Pick one of these:
Make your list/array of objects-to-delete be a 'set' or implemented in such a way that duplicates are avoided.
Check for existence of your object in the world
The collision only happens between 2 objects in Box2D. So in your mentioned scenario your will get multiple collision events which could be,
Enemy-1 and Enemy-2
Enemy-1 and Bullet
Enemy-2 and Bullet
So one possible reason of crash could be that you are not expecting (Enemy-1 and Enemy-2) collision and you are handling it like you have collision between (Enemy-1 and Bullet) so you might be casting it into wrong class. Make sure you are checking the kind of class "isKindOf" before casting it.
Also you may want to use Contact Filtering and or assign category masks to your enemies so that they don't collide with each other and only collide with bullet.
But it will be more help full if you tell something about how and where you destroy your bodies (I hope its not inside your Collision Detection Functions) and also if you can share the exception text when your application crash, that will be helpful.
I used a rather cheap workaround. I alternately created enemy fixtures of different sizes(differing by few pixels). So now if i shoot them even when they overlap, the app doesn't crash(because only the bigger object collides and gets destroyed). This serves my purpose. Thanx a llot for your help. I really appreciate it! :)
I have worked out how to detect touching on an object using glReadPixels but how would I detect if a object hits another object (a bullet for example).
I cant do that with detecting colours.
As others have said, do this in the object model, not in the graphics.
For one simple model, give each object other than a bullet a size. Then check if a bullet's location is within that object's radius every tick. In pseudocode:
for each bullet
for each hittableObjectInWorld
if ([hittableObject isTouchedBy:bullet]) {/*handle collision*/}
endFor
endFor
hittableObject::isTouchedBy:(Sprite *)otherObject {
xDistance = [self x] - otherObject.x;
yDistance = [self y] - otherObject.y;
totalDistance = sqrt((xDistance*xDistance) + (yDistance*yDistance));
if (totalDistance <= [self size]) return YES;
else return NO;
}
Now you've got a simple collision detection system. There are some abstractions here: We treat every hittable object as if it were shaped like a sphere with its 'size' as its radius. Bullets are pinpoint small, but you can correct for that by adding a bullet's radius to the radius of each of the hittable objects and it makes the math run a wee bit faster this way.
This might be the simplest possible collision detection system. There's a lot of room for improvement here. The big thing is you're doing the number of bullets times the number of hittable objects checks each tick. If you have many bullets and many objects in the world, that can be a lot of processor time. There's all sorts of hacks to cut down on the number of checks you have to do. If you run into speed problems with this version, that's the next thing to start tuning up.
Good luck!
You do it in your object model, not in your graphics code. OpenGL is only tangentially related to collision detection.
OpenGL only deals with the graphical display of your game's objects. Any logic about how the objects in your game behave should be done in the code that manages the state of the objects not in the OpenGL graphics code.
What you are looking for is collision detection which can be a fairly deep topic. Just to be clear, once you detect a collision (e.g. a bullet hitting an object) you will more than likely run some OpenGL code to display the reaction of the collision to the user but the actual detection of the collision should not occur within the OpenGL realm.
Lastly, if you find all of this a bit overwhelming I would recommend the use of a game engine like cocos2d or Unity.
Fairly simple question that Im sure you will laugh at me for.
I have two rectangles playerRect and wall.
I have an if statement with the condition being ..
if (CGRectIntersectsRect(playerRect,wall)) {
//handle collision here
}
The problem I'm having is working out which side actually hit the wall rectangle.
I need to know because then I stop te player from moving depending on which side hit.
Thanks for any help
Disco
I would add some direction property to my 'Player' object. This way when you detect a collision, you just check to see which way the player was moving prior to the collision and react accordingly.
Create a CGRect for each side of your object with just a width of 1 (or height of 1 depending on the side) and look for intersections with the sides instead of the entire object. If your object is moving faster than 1 pixel per collision check, then you would check the sides in addition to checking the entire object