How do you determine if two sprites that are currently running actions have collided?
Sprite Collision Detection
(17 posts) (5 voices)-
Posted 2 years ago #
-
check if their bounds intersect.
Posted 2 years ago # -
I have the following:
CGPoint firePoint = CGPointMake(fire.position.y,fire.position.x); CGRect rect1 = [self positionRect:fire]; CGRect rect2 = [self positionRect:monster]; if(CGRectContainsPoint(rect2, firePoint)) { //if (!CGRectIsNull(CGRectIntersection(rect1, rect2))) { [self removeMonsterSprite]; [self removeSprite]; }and I have tried both the CGRectContainsPoint and CGRectIntersection
neither one registers a detection while im firing. Both the fire and monster sprites are sprites travelling from point A to B under actions. and the entire snippet is in "-(void) step: (ccTime) delta" . Is there something else I have to do?
Posted 2 years ago # -
Osiris:
Stupid question, but are you sure 'step' is being called? Did you schedule it?
Also, I'm assuming positionRect is a custom method? What is the self you are sending this message to? A layer containing the sprites?
-CJL
Posted 2 years ago # -
Is your sprite created on-the-go or did you subclass it?
if you subclassed it, and added a sprite to it as a child - I found out that it won't change the contentSize, but stay as(width=0, height=0)and you have to change it to the content size of the sprite added as a child.Bottom line, we need more code to determine your problem.
You can also try a physics engine - they make life a whole lot easier.Posted 2 years ago # -
I don't see why either function would not be working so I bet your code isn't being called at the right time. If you really think something is wrong with the check check the value at runtime with the debugger.
Posted 2 years ago # -
@cjl - Im creating the scedule at the end of my init method....
self schedule: @selector(step:) interval: 1.0 / 60.0];and yes, PositionRec: was a method for creating a CGRect from a sprite.
-(CGRect) positionRect: (Sprite*)mySprite { CGSize contentSize = [mySprite contentSize]; CGPoint contentPosition = [mySprite position]; CGRect result = CGRectOffset(CGRectMake(0, 0, contentSize.width, contentSize.height), contentPosition.x-contentSize.width/2, contentPosition.y-contentSize.height/2); return result; }The rest of the movements are working find. I have ships and enemies and bullets all moving by actions and being directed by touch control. That part works fine, I think my step: method is being called appropriately.
@natanavra - :) now you are getting into that magic I barely understand. I wanted to grasp a basic understanding of programming this thing before I went and added a layer of physics.
Actually, in looking at the code to try and answer the questions, I noticed I was not looking for the Intersection of the monster and the bullet, but rather the monster and the fire button (DOH!) I changed it and I am at least further along.
These sessions are very therapeutic as it gets you to think more objectively when people are asking questions!
Thanks! and hopefully, the next time, I'll even know what sub classing is! I'll take a couple of hours tonight to study some theory! A month ago, I hadn't even heard of objective C before.
Posted 2 years ago # -
I can tell that its trying to work now...
however,
im trying to use the
if (!CGRectIsNull(CGRectIntersection(rect1, rect2))) {that I had commented out before as opposed to
if(CGRectContainsPoint(rect2, bulletPoint)) {the CGrectIntersection(rect1,rect2) appears to be triggered all the time. Most of the time the two sprites are not even near each other.
(of course I have changed all reference to "fire" to "bullet" instead :) )
Is this because of what Natanavra was saying before about sub-classing?
Posted 2 years ago # -
I just checked and my bullet.ContentSize.width = 128 (the original size of the sprite)
Could it be that the original size of the bullet is being compared to the original size of the monster?
Posted 2 years ago # -
If your scaling your sprites, don't forget to scale the values used to create your rect's.
Posted 2 years ago # -
The other thing is that I'm running the movement of the monster as an action. I'm checking collisions and updating hit detection in my step: method, but I think the action is still running? How do I tell the action it can stop now and reset?
Posted 2 years ago # -
Im now detecting the collision. I have an NSLog() in the snippet that does the detection, so I know thats good.
I have the following code in there now:
if(CGRectContainsPoint(rect2, bulletPoint)) { NSLog(@"***Collision***"); monster_flag = NO; [monster setVisible:NO]; [monster setScale:0.1]; monster.position = CGPointMake(240.0f, 160.0f); [bullet setVisible:NO]; }my monster is immediately reinited as I havent written any more logic yet, BUT... it is SUPPOSED to shrink back down and return to the center of the screen to start creeping up a tunnel again.
What it IS doing is setVisible seems to work, it momentarily blanks out and the action either continues where it left off or restarts from the monosters last position. The action tells the monsters to grow 10x over the 2 secs its supposed to climb out the tunnel (appearing to get larger - and it does it perfectly, until the collision) But once its collided, it doesnt seem to get the idea that it is supposed to reinitialze at 10% its size and return to center of the screen?
Posted 2 years ago # -
PhilM - how do you scale a rect? just scale the x and y by the scale property of the original sprite?
Posted 2 years ago # -
If your calling positionRect before each check then that shouldn't matter, as your recalculating the rect anyway.
Something along the lines of this (not tested, so you might need to check it against the api)
CGRect result = CGRectOffset(CGRectMake(0, 0, (contentSize.width * mySprite.scaleX), (contentSize.height * mySprite.scaleY)), contentPosition.x-(contentSize.width * mySprite.scalx)/2, contentPosition.y-(contentSize.height * mySprite.scaleY)/2);
Posted 2 years ago # -
Thanks!!
I plopped it into:
- (CGRect)makeRect:(Sprite *)mySprite { return CGRectMake(mySprite.position.x - (mySprite.contentSize.width*mySprite.scale) /2, mySprite.position.y - (mySprite.contentSize.height*mySprite.scale) / 2, (mySprite.contentSize.width*mySprite.scale), (mySprite.contentSize.height*mySprite.scale)); }and it seemed to help a great deal with the accuracy!
Thanks!Posted 2 years ago # -
no probs ; )
Posted 2 years ago #
Reply
You must log in to post.