Можно ли деактивировать столкновения в физических телах в spriteKit?

Я смотрю, как лучше всего собирать предметы с моим героем в моей игре spriteKit для iOS, и после того, как попробовать несколько способов сделать это, мой вывод - лучший способ иметь элемент с физическое тело, которое может обнаруживать столкновения, но не сталкивается с моим героем. Можно ли это сделать? дезактивировать столкновения физического тела без деактивации его возможностей для обнаружения столкновений? Звучит немного противоречиво, я знаю... Потому что другим способом было бы создать только SKSpriteNode без физического тела, тогда не было бы столкновений, но способ "обнаружить" столкновения был бы сделан вручную и намного сложнее, потому что мне нужно будет установить обнаружение системы координат у моего героя, что, когда он будет находиться в этих спецификациях (над элементом), я заставлю элемент исчезнуть. Любая идея о том, как сделать любой из этих двух способов проще?

Ответ 1

Отъезд collisionBitMask, categoryBitMask и contactTestBitMask в классе SKPhysicsBody.

По сути, физические тела с тем же значением collisionBitMask будут "проходить через" друг друга.

  • Коррекция: Если бит категории и столкновений соответствует, они будут взаимодействовать. Если они не соответствуют, эти два будут не взаимодействовать. И если бит столкновений и биты категории оба ноль, конечно, этот элемент будет взаимодействовать без ничего.

Затем вы устанавливаете значения categoryBitMask и contactTestBitMask для создания объекта SKPhysicsContact Object on contact. Наконец, ваш класс должен принять протокол SKPhysicsContactDelegate. Используйте метод - didBeginContact: для обнаружения и обработки объекта SKPhysicsContact.

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

Короткий ответ:

yourHero.physicsBody.collisionBitMask = 0;

Значение по умолчанию collisionBitMask равно 0xFFFFFFFF (все биты установлены), поэтому node сталкивается с другими

Ответ 3

вы можете сделать это, установив categoryBitMask и contactBitMasks проигрывателя и объекты объекта, но убедитесь, что вы не устанавливаете collisionBitMask для взаимодействия друг с другом (см. ниже)

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;

таким образом физическое тело будет захватывать столкновения между игроком и объектами мира, предметными и мировыми объектами, но не между игроком и предметами. Он вызовет вызов didBeginContact, где вы можете удалить свой элемент node, добавить здоровье и т.д.

Надеюсь, это поможет!

Ответ 4

contactTestBitMask используется для запуска didBeginContact. collisionBitMask используется для активации физики на узлах.

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