So for the App I'm working on, I have two cubes colliding. I check for this in the standard way. The app tells me when they collide in my "didBeginContact" method.
-(void)didBeginContact:(SKPhysicsContact *)contact {
if (contact.bodyA.categoryBitMask == WALL_CATEGORY && contact.bodyB.categoryBitMask == CHARACTER_CATEGORY) {
CGPoint point = contact.contactPoint;
}
}
So i know where the collision takes place, but because it is two squares it can be at any point along the side including the corners. So how would I check if the collision on the left/right/top/bottom exclusively?
Edit: Correct Answer: Might not be the cleanest way to do it but it works. Hopefully it'll help someone in the future.
m_lNode = [SKNode node];
m_lNode.position = CGPointMake(-(CHARACTER_SIZE / 2), 0);
m_lNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(1, m_character.size.height)];
m_lNode.physicsBody.allowsRotation = NO;
m_lNode.physicsBody.usesPreciseCollisionDetection = YES;
m_lNode.physicsBody.categoryBitMask = CHARACTER_L_CATEGORY;
m_rNode = [SKNode node];
m_rNode.position = CGPointMake((CHARACTER_SIZE / 2), 0);
m_rNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(1, m_character.size.height)];
m_rNode.physicsBody.allowsRotation = NO;
m_rNode.physicsBody.usesPreciseCollisionDetection = YES;
m_rNode.physicsBody.categoryBitMask = CHARACTER_R_CATEGORY;
m_tNode = [SKNode node];
m_tNode.position = CGPointMake(0, (CHARACTER_SIZE / 2));
m_tNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(m_character.size.width , 1)];
m_tNode.physicsBody.allowsRotation = NO;
m_tNode.physicsBody.usesPreciseCollisionDetection = YES;
m_tNode.physicsBody.categoryBitMask = CHARACTER_T_CATEGORY;
m_bNode = [SKNode node];
m_bNode.position = CGPointMake(0, -(CHARACTER_SIZE / 2));
m_bNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(m_character.size.width, 1)];
m_bNode.physicsBody.allowsRotation = NO;
m_bNode.physicsBody.usesPreciseCollisionDetection = YES;
m_bNode.physicsBody.categoryBitMask = CHARACTER_B_CATEGORY;
[m_character addChild:m_tNode];
[m_character addChild:m_bNode];
[m_character addChild:m_lNode];
[m_character addChild:m_rNode];
-(void)didBeginContact:(SKPhysicsContact *)contact {
if (contact.bodyA.categoryBitMask == WALL_CATEGORY) {
switch (contact.bodyB.categoryBitMask) {
case CHARACTER_T_CATEGORY:
NSLog(@"Top");
m_isHitTop = true;
break;
case CHARACTER_B_CATEGORY:
NSLog(@"Bottom");
m_isHitBottom = true;
break;
case CHARACTER_L_CATEGORY:
NSLog(@"Left");
m_isHitLeft = true;
break;
case CHARACTER_R_CATEGORY:
NSLog(@"Right");
m_isHitRight = true;
break;
}
}
}
Added some relevant code. It's my code so there is variables amongst other things but you should be able to figure it out.
I think the best way to determine what side is involved in your contact (top,left,bottom,right side) is to:
let halfWidth = self.frame.width/2
let halfHeight = self.frame.height/2
let down = CGPointMake(self.frame.origin.x+halfWidth,self.frame.origin.y)
let up = CGPointMake(self.frame.origin.x+halfWidth,self.frame.origin.y+self.frame.size.height)
let left = CGPointMake(self.frame.origin.x,self.frame.origin.y+halfHeight)
let right = CGPointMake(self.frame.origin.x+self.frame.size.width,self.frame.origin.y+halfHeight)
This step can be possible with this little function:
func getDistance(p1:CGPoint,p2:CGPoint)->CGFloat {
let xDist = (p2.x - p1.x)
let yDist = (p2.y - p1.y)
return CGFloat(sqrt((xDist * xDist) + (yDist * yDist)))
}
After, the point involved with the lowest distance calculated is the side point nearest the contactPoint.
What are the advantages of this method:
the easiest way is to add child sprites the top, left, right, bottom of your squares. Add physics bodies to those, and then you can tell where things are colliding. I'd recommend trying this method first unless you have many many squares on the screen.
If you have a ton of squares on the screen and youre worried about performance. then maybe use contact.contactPoint
and convert that point to square coordinates. given the center point of the square, the angle of the squares rotation and that point, you should be able to tell where the square collided. That would require some math.. and I was afraid writing up that kind of solution when the first one may be all that you really need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With