I\'m looking at doing the best way to collect items with my hero in my spriteKit game for iOs, and after to try a few ways to do it, my conclusion is the best way would be t
Check out collisionBitMask, categoryBitMask, and contactTestBitMask in the SKPhysicsBody
class.
Essentially, physics bodies with the same collisionBitMask
value will "pass-through" each other.
Then, you set the categoryBitMask
and contactTestBitMask
values to create an SKPhysicsContact
Object on contact. Finally, your Class should adopt the SKPhysicsContactDelegate
protocol. Use the - didBeginContact:
method to detect and handle the SKPhysicsContact
object.
static const uint8_t heroCategory = 1;
static const uint8_t foodCategory = 2;
--
food.physicsBody.categoryBitMask = foodCategory;
food.physicsBody.contactTestBitMask = heroCategory;
food.physicsBody.collisionBitMask = 0;
--
hero.physicsBody.categoryBitMask = heroCategory;
hero.physicsBody.contactTestBitMask = foodCategory;
hero.physicsBody.collisionBitMask = 0;
--
-(void)didBeginContact:(SKPhysicsContact *)contact {
SKPhysicsBody *firstBody = contact.bodyA;
SKPhysicsBody *secondBody = contact.bodyB;
}
Short answer:
yourHero.physicsBody.collisionBitMask = 0;
The default value of collisionBitMask
is 0xFFFFFFFF (all bits set), that's why the node collides with others
contactTestBitMask
is used to trigger didBeginContact
. collisionBitMask
is used to activate physics on nodes.
// add a physics body
ship.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ship.size.width/2];
// set the category for ship
ship.physicsBody.categoryBitMask = shipCategory;
// detect collisions with asteroids and edges
ship.physicsBody.contactTestBitMask = asteroidCategory | edgeCategory;
// physically collide with asteroids
ship.physicsBody.collisionBitMask = asteroidCategory;
you can do this by setting the categoryBitMask and contactBitMasks of the player and the item objects, but making sure that you do not set the collisionBitMask for either to interact with each other (see below)
static const int playerCategory = 1;
static const int worldCategory = 2;
static const int objectCategory = 4;
....
SKSpriteNode *player, *item;
....
player.physicsBody.categoryBitMask = playerCategory;
player.physicsBody.collisionBitMask = worldCategory;
player.physicsBody.contactTestBitMask = worldCategory;
....
item.physicsBody.categoryBitMask = objectCategory;
item.physicsBody.contactTestBitMask = playerCategory | worldCategory;
item.physicsBody.collisionBitMask = worldCategory;
this way the physics body will pick up collisions between the player and world objects, the item and world objects, but not between the player and items. It will trigger a call to didBeginContact, where you can delete your item node, add health, etc.
Hope this helps!