Swift - Случайные столкновения не обнаружены

В своей игре я использую SKSprite. Некоторые столкновения не обнаружены. Я сделал 10 попыток, коллизии работают хорошо, но около 25% столкновений, которые должны быть обнаружены, не обнаруживаются. Я понятия не имею, почему, я пробовал много вещей. Коллизии бывают только с узлами одной категории.

Я понятия не имею, почему случайно некоторые столкновения не происходят, когда я их явно вижу, у вас есть идеи? Спасибо за вашу помощь.

Вот код didBeginContact:

func didBeginContact(contact: SKPhysicsContact) {

    var firstBody: SKPhysicsBody = contact.bodyA
    var secondBody: SKPhysicsBody = contact.bodyB

    if firstBody.categoryBitMask == secondBody.categoryBitMask {

            listContacts.append([firstBody.node!,secondBody.node!])
        }

    }
}

Вот код didEndContact:

func didEndContact(contact: SKPhysicsContact) {

    var firstBody: SKPhysicsBody = contact.bodyA
    var secondBody: SKPhysicsBody = contact.bodyB

    if contact.bodyA.categoryBitMask == contact.bodyB.categoryBitMask {

        for i in listContacts{

            if (i.contains(firstBody.node!) && i.contains(secondBody.node!)){

                let findIndex = listContacts.indexOf { $0 == i }
                listContacts.removeFirst(findIndex!) 
            }
        }

    }

Наконец, когда я объявляю новый SKSpriteNode, я устанавливаю это:

rectangle.physicsBody = SKPhysicsBody(rectangleOfSize: rectangle.size)
rectangle.physicsBody?.dynamic = true 
rectangle.physicsBody?.collisionBitMask = PhysicsCategory.None

usePreciseCollisionDetection = true ничего не меняет, поэтому я не использую usePrecisionCollisionDetection

Каждый SKSpriteNode имеет свои categoryBitmask и contactTestBitmask равные, потому что должны сталкиваться только одни и те же SKSpriteNodes.

Также:

physicsWorld.gravity = CGVectorMake(0, 0)
physicsWorld.contactDelegate = self

Наконец, вот короткое видео моей игры, если вы хотите легко понять, что происходит (проблема столкновений между прямоугольниками) https://www.youtube.com/watch?v=-pbmKwQiE9U


person Oscar Falmer    schedule 17.06.2016    source источник
comment
Не могли бы вы опубликовать свои сенсорные функции? Похоже, вы нажимаете в своем видео, чтобы удалить блоки, верно?   -  person Siriss    schedule 17.06.2016
comment
@ Siriss, вы правы, но это ОГРОМНАЯ функция, и я провел много тестов, я знаю, что это происходит из-за обнаружения столкновений, потому что listContacts не имеет соединений, поэтому я не думаю, что это поможет, к сожалению. По сути, сенсорная функция проверяет, какие прямоугольники находятся рядом с ней, используя listContacts, а затем, если есть минимум 3 рядом друг с другом одного цвета, они исчезнут.   -  person Oscar Falmer    schedule 17.06.2016


Ответы (2)


Кажется, вы проверяете, равно ли categoryBitMask тела A телу B.

if firstBody.categoryBitMask == secondBody.categoryBitMask {

        listContacts.append([firstBody.node!,secondBody.node!])
    }

}

Это запустит действие только в том случае, если узел попадет в узел с тем же categoryBitMask

Вы должны проверить collisionBitMasks, чтобы увидеть, есть ли у вас коллизия, или вы можете проверить имя.

Например, используя categoryBitMask, вы можете сделать что-то вроде этого:

func didBeginContact(contact: SKPhysicsContact) {

    var sprite: SKSpriteNode!

    if contact.bodyA.categoryBitMask == <your category bitmask> {
        sprite = contact.bodyA.node! as! SKSpriteNode
    }
    else if contact.bodyB.categoryBitMask == <your category bitmask> {
        sprite = contact.bodyB.node! as! SKSpriteNode
    }

    // Do something with sprite....
    // You can also create another sprite, and assign it to the other body, and perform functions on it, or both A and B.
    // It is good to have different functions you send can send the nodes to once you find out which ones they are.

}

Вы можете выполнить эти проверки, чтобы увидеть, какие спрайты сталкиваются друг с другом.

person Siriss    schedule 17.06.2016
comment
Спасибо за ваш ответ, я только что попробовал и сделал его похожим на ваш код, это ничего не меняет, все та же проблема. Он делает то же самое, потому что мне нужно обнаруживать коллизии между узлами одной и той же категорииBitMask. - person Oscar Falmer; 17.06.2016
comment
Я только что добавил видео в свой пост, если вы хотите увидеть, как выглядит игра. - person Oscar Falmer; 17.06.2016

Я только что исправил это! Причина была в том, что в функции "touchesEnded" у меня была рекурсивная функция, которая удаляла плохие соединения в listContacts!

person Oscar Falmer    schedule 17.06.2016