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

爷,独闯天下 提交于 2019-12-28 17:31:18

问题


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 to have an item with a physic body which can detect collisions but don't collide with my hero. Is it possible to do it? to deactivate collisions of a physic body without deactivating its capabilities to detect collisions?? Sounds a bit contradictory I know... Because, the other way would be to create only a SKSpriteNode without physic body, then there wouldn't being collisions, but the way to "detect" collisions would be hand made and much more harder, because i would need to set a coordinate system detection in my hero, that when he will be in those specifics coordinates (over the item) then i'll make the item disappears. Any idea of how to do any of the two ways easier?


回答1:


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;
}



回答2:


Short answer:

yourHero.physicsBody.collisionBitMask = 0;

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




回答3:


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!




回答4:


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;


来源:https://stackoverflow.com/questions/21267600/is-it-possible-to-deactivate-collisions-in-physics-bodies-in-spritekit

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!