Is it possible to deactivate collisions in physics bodies in spriteKit?

前端 未结 4 1857
栀梦
栀梦 2020-12-09 19:12

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

相关标签:
4条回答
  • 2020-12-09 19:25

    Check out collisionBitMask, categoryBitMask, and contactTestBitMask in the SKPhysicsBody class.

    Essentially, physics bodies with the same collisionBitMask value will "pass-through" each other.

    • Correction: If the category and collision bits match, they will interact. If they do not match, those two will not interact. And if the collision bits, and category bits, are both zero, of course that item will interact with nothing whatsoever.

    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;
    }
    
    0 讨论(0)
  • 2020-12-09 19:25

    Short answer:

    yourHero.physicsBody.collisionBitMask = 0;
    

    The default value of collisionBitMask is 0xFFFFFFFF (all bits set), that's why the node collides with others

    0 讨论(0)
  • 2020-12-09 19:43

    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;
    
    0 讨论(0)
  • 2020-12-09 19:46

    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!

    0 讨论(0)
提交回复
热议问题