Question

I'm creating a game which will need to use a lot of collision detection and i'm only learning about it today.

Now I have two SKSpriteNodes but one is a child of an SKNode. The SKSpriteNode without a parent is called character and the sprite with the parent is called buildingStructure.

Now character's category is static const uint32_t playerCategory = 0x1 << 20; and buildingStructure's category is _buildingStructureCategory = 0x1 << 0;. buildingStructure's category is set in another class map.m through a @property.

The variables pass over correctly to another class called main.m (which is where the charactercategory is set). I create character with a method, setting his physics body, position and so on.

character's properties

character.name = @"character";
character.size = CGSizeMake(250, 400);
character.zPosition = 500;
character.position = CGPointMake(self.scene.size.width/2, self.scene.size.height/2+200);
character.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:character.size];
character.physicsBody.restitution = 0;
character.physicsBody.density = 0.1;
character.physicsBody.allowsRotation = NO;
character.physicsBody.categoryBitMask = playerCategory;
character.physicsBody.collisionBitMask = categoryBitManager.buildingStructureCategory;

buildingStructure's properties

buildingStructure.name = @"buildingStructure";
buildingStructure.position = CGPointMake(building.position.x, building.position.y);
buildingStructure.size = CGSizeMake(500, 400);
buildingStructure.physicsBody.dynamic = NO;

buildingStructure.physicsBody.categoryBitMask = _buildingStructureCategory;

On the other hand buildingStructure doesn't have a set physicsBody because I want character to pass through buildingStructure but I also want it to detect when character is 'on top' of buildingStructure to perform an action.

Since buildingStructure doesn't have a defined physicsBody is this what's causing didBeginContact:contact to not recognise the collision contact?

Was it helpful?

Solution

The physicsBody property of an SKNode (or subclass of) is nil by default. Yes give the buildingStructure a physics body and correctly configure it to achieve the desired behaviour.

To get the desired behaviour between two physics bodies, first understand that there are 'collisions' and there are 'contacts'. SKPhysicsBody has two properties named collisionBitMask and contactTestBitMask.

For collisionBitMask the default value is 0xFFFFFFFF (all bits set), and for contactTestBitMask the default value is 0x00000000 (all bits cleared). You can see that by defaults every physics body will collide with others but there will be no contact.

A collision is where you want the physics simulation to affect the body in question, where a contact is where you want to be notified so you can do something. So this will call didBeginContact:

I suggest setting the collisionBitMask for both bodies to 0 (so their physics is not affected and pass through one another). Then set the contactTestBitMask property of character to that of the building like this-

character.physicsBody.contactTestBitMask = categoryBitManager.buildingStructureCategory;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top