Как обнаружить контакт на разных участках физического тела

Я хотел бы добиться классического эффекта "выстрел в голову" в игре спрайт-кит.

Мои идеи и попытки:

  1. Создайте отдельные физические тела 'body' и 'head' на одном и том же спрайте и прикрепите их к соединению. Невозможно:(

  2. Создайте физическое тело "тело" на "вражеском" спрайте и создайте еще один прозрачный спрайт с физическим телом "голова", которое следует за телом (сидит сверху). Этот подход требует, чтобы я отслеживал, какая голова связана с каким телом. Это также снизит эффективность игр. Мне любопытно, если бы я мог создать подкласс SKSpriteNode и создать "врага", который бы связал эти два спринтода и физические тела.

  3. Проверьте расположение снаряда против врага, чтобы увидеть, вступил ли снаряд в определенный диапазон Y на вершину спрайта. Я считаю, что это будет неэффективно, поскольку снаряды летят довольно быстро.

Буду признателен, если кто-нибудь создал этот эффект и сможет поделиться своими знаниями. Спасибо!

2 ответа

Решение

Я использую эту настройку во многих местах. Он хорошо масштабируется, если вы хотите добавить больше деталей или оружия, и позволяет легко визуально скрыть любую из этих частей или оружия. Использование userData может пригодиться, если у вас много чего происходит, и у разных врагов разные "вещи", или вы делаете сумасшедшие вещи, такие как воспитание дочерних спрайтов для разных сущностей на основе игрового процесса и т. Д.

-(SKSpriteNode*)makeAnEnemy
{

    SKSpriteNode *mainEnemy;
    SKSpriteNode *enemyHead;
    //setup mainEnemy physics body
    //setup enemyHead physics body
    [mainEnemy addChild:enemyHead];

    // depending on your plans, on hit you could use the following code later:
    SKSpriteNode *theEnemyThatWasHit = (SKSpriteNode*)enemyHead.parent;

    //or you can use userdata and set it all up here
    [mainEnemy.userData setObject:enemyHead forKey:@"myHead"];
    [enemyHead.userData setObject:mainEnemy forKey:@"myBody"];

    return mainEnemy;
}

С использованием pinned Атрибут PhysicsBody позволяет легко создавать сложные спрайты с несколькими зонами контакта. Прикрепление физического тела к родителю узла:

Значением по умолчанию является НЕТ. Если ДА, то положение узла является фиксированным относительно его родителя. Положение узла не может быть изменено действиями или физическими силами. Узел может свободно вращаться вокруг своей позиции в ответ на столкновения или другие силы. Если родительский узел имеет физическое тело, то два физических тела обрабатываются так, как если бы они были соединены штифтовым соединением.

Вот базовый класс Dog, где у собаки основное тело и голова. Обратите внимание, что я установил allowsRotation = false так что голова не может двигаться вокруг тела.

import SpriteKit

// for readability
let mainSize = CGSize(width: 300, height: 300)
let headSize = CGSize(width: 100, height: 100)

class Dog : SKSpriteNode {

    let head = SKSpriteNode(color: SKColor.greenColor(), size: headSize)

    init() {
        super.init(texture: nil, color: SKColor.redColor(), size: mainSize)

        head.position = CGPoint(x: mainSize.width - headSize.width, y: 0)
        addChild(head)
    }

    // called after Dog has been added to the scene
    func configurePhysicsBody() {

        physicsBody = SKPhysicsBody(circleOfRadius: mainSize.width / 2)
        physicsBody.dynamic = true
        physicsBody.allowsRotation = false
        // set contactBitmask for main body

        head.physicsBody = SKPhysicsBody(circleOfRadius: headSize.width / 2)
        head.physicsBody.dynamic = true
        head.physicsBody.allowsRotation = false
        // The head is pinned to the parent node, so position is fixed relative to parent
        head.physicsBody.pinned = true
        // set contactBitmask for head

    }

}

введите описание изображения здесь

Другие вопросы по тегам