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

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

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

  1. Создайте отдельные физические тела «тела» и «головы» на одном и том же спрайте и соедините их с помощью соединения. Невозможный :(

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

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

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


person meisenman    schedule 08.07.2014    source источник
comment
1. должно быть возможно, особенно с iOS 8, где, как я полагаю, теперь вы можете создавать многоформенные тела. Хотя даже косяк с очень жестким поведением должен работать. 2. будет альтернативой и требует только, чтобы тело и спрайт головы были дочерними элементами спрайта тела, и обновляли положение головы в каждом кадре, чтобы она оставалась с тем же смещением относительно тела. Очень просто и эффективно.   -  person LearnCocos2D    schedule 08.07.2014
comment
@LearnCocost2D iOS 8 позволяет создавать тела с несколькими формами с помощью SKPhysicsBody.bodyWithBodies(), но используются только формы. К сожалению, вы не можете установить CollisionBitMask для отдельных тел. Этот вопрос также помогает автору моей помощи: тела на один узел">stackoverflow.com/questions/18993219/   -  person Jon    schedule 08.07.2014
comment
@LearnCocos2D Спасибо за подробное описание того, как успешно реализовать метод 2! Это позволит мне сохранить два спрайта вместе, не нарушая простоты физики наборов спрайтов. (индивидуально отслеживая врагов)   -  person meisenman    schedule 08.07.2014
comment
@Jon Я тоже нашел этот вопрос, однако мои снаряды удаляются при контакте, поэтому меня действительно интересуют только contactBitMasks и какой раздел был поражен. (голова или тело)   -  person meisenman    schedule 08.07.2014
comment
@meisenman Мне было бы интересно увидеть вашу реализацию, как только вы это сделаете. Мне нужно сделать то же самое, но я еще не дошел до этого.   -  person Jon    schedule 08.07.2014
comment
@Джон Абсолютно! Я должен быть в состоянии ударить это в эти выходные в мое свободное время.   -  person meisenman    schedule 08.07.2014
comment
@Jon Кажется, у нас уже есть проверенный ответ.   -  person meisenman    schedule 08.07.2014


Ответы (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;
}
person Cooper Buckingham    schedule 08.07.2014
comment
Сдвинет ли это голову относительно тела, если над телом будет совершено действие? - person meisenman; 08.07.2014
comment
Да, вы просто относитесь к врагу как к единому существу, все его дочерние спрайты придут вместе с ним. Например, в одном из моих проектов у меня есть голова и плащ, и голова и плащ выполняют свои собственные действия в цикле, просто чтобы выглядеть красиво, но главный враг — это единственный спрайт, который я на самом деле позиционирую в мир. - person Cooper Buckingham; 08.07.2014
comment
@CHBuckingham Не могли бы вы рассказать о своих физических конфигурациях тела? Я создал персонажа собаки с телом и головой, где голова является дочерним элементом основного тела собаки. Голова не двигается относительно основного тела. Два физических тела обрабатываются независимо... так что голова просто падает на землю. - person Jon; 10.07.2014
comment
Вы не можете заставить физические тела двигаться под действием физики. Они были бы просто для проверки контактов, как выстрел в голову. Я полагаю, если вам нужно, чтобы они двигались по физике, вы могли бы использовать фиксированное соединение. - person Cooper Buckingham; 10.07.2014

Использование атрибута pinned объекта physicsBody упрощает создание сложных спрайтов с несколькими контактными зонами. Прикрепление физического тела к родительскому узлу:

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

Вот базовый класс 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

    }

}

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

person Jon    schedule 11.07.2014
comment
Это тоже отличный ответ. Я еще не в быстром :/ - person meisenman; 12.07.2014