Spritkit: обнаружение столкновения при рисовании линии с помощью пальца - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь обнаружить столкновение contactPoint между existing line и линией, пользователь которой currently drawing using finger.

Вот мой код:

let padding: CGFloat = 100
override func didMove(to view: SKView) {

    physicsWorld.contactDelegate = self

    let startPoint1 = CGPoint(x: self.frame.minX + padding , y: self.frame.minY + padding)
    let leftHorizontalPoint = CGPoint(x: self.frame.minX + padding, y: self.frame.maxY - padding)

    let line1 = SKShapeNode()
    let line_path:CGMutablePath = CGMutablePath()
    line_path.move(to: startPoint1)
    line_path.addLine(to: leftHorizontalPoint)
    line1.path = line_path
    line1.lineWidth = 3
    line1.strokeColor = UIColor.white
    addChild(line1)

    line1.physicsBody = SKPhysicsBody(edgeLoopFrom: line1.frame)
    line1.physicsBody?.isDynamic = true
    line1.physicsBody?.categoryBitMask = PhysicsCategory.solidLine
    line1.physicsBody?.collisionBitMask = PhysicsCategory.currentLine
    line1.physicsBody?.contactTestBitMask = PhysicsCategory.currentLine
}

Затем на touchBegin, touchMove & touchEnd у меня следующий код:

var currentLineNode: SKShapeNode!
var startPoint: CGPoint = CGPoint.zero
func touchDown(atPoint pos : CGPoint) {
    startPoint = pos
}

func touchMoved(toPoint pos : CGPoint) {
    if currentLineNode != nil {
        currentLineNode.removeFromParent()
    }
    currentLineNode = SKShapeNode()
    currentLineNode.zPosition = 1
    let line_path:CGMutablePath = CGMutablePath()
    line_path.move(to: startPoint)
    line_path.addLine(to: pos)
    currentLineNode.path = line_path
    currentLineNode.lineWidth = 3
    currentLineNode.strokeColor = UIColor.red
    addChild(currentLineNode)

    currentLineNode.physicsBody = SKPhysicsBody(edgeLoopFrom: currentLineNode.frame)
    currentLineNode.physicsBody?.isDynamic = true
    currentLineNode.physicsBody?.categoryBitMask = PhysicsCategory.currentLine
    currentLineNode.physicsBody?.collisionBitMask = PhysicsCategory.solidLine
    currentLineNode.physicsBody?.contactTestBitMask = PhysicsCategory.solidLine
}

func touchUp(atPoint pos : CGPoint) {
    if currentLineNode != nil {
        currentLineNode.removeFromParent()
    }
    currentLineNode = SKShapeNode()
    let line_path:CGMutablePath = CGMutablePath()
    line_path.move(to: startPoint)
    line_path.addLine(to: pos)
    currentLineNode.path = line_path
    currentLineNode.lineWidth = 3
    currentLineNode.strokeColor = UIColor.red
    addChild(currentLineNode)

    currentLineNode.physicsBody = SKPhysicsBody(edgeLoopFrom: currentLineNode.frame)
    currentLineNode.physicsBody?.isDynamic = true
    currentLineNode.physicsBody?.categoryBitMask = PhysicsCategory.currentLine
    currentLineNode.physicsBody?.collisionBitMask = PhysicsCategory.solidLine
    currentLineNode.physicsBody?.contactTestBitMask = PhysicsCategory.solidLine
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    for t in touches { self.touchDown(atPoint: t.location(in: self)) }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchMoved(toPoint: t.location(in: self)) }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}

physicsWorld's contactDelegate следующим образом: (Делегат даже не выполнен)

extension GameScene : SKPhysicsContactDelegate {
    func didBegin(_ contact: SKPhysicsContact) {
       // This never get detected :(
       print(contact.contactPoint)
       var firstBody: SKPhysicsBody
       var secondBody: SKPhysicsBody
       if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
           firstBody = contact.bodyA
           secondBody = contact.bodyB
       } else {
           firstBody = contact.bodyB
           secondBody = contact.bodyA
       }
    }
}

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

enter image description here

Что может быть не так? Любое предложение по этому вопросу будет полезно.

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

вы создаете свое физическое тело с помощью петли ребра. Apple определяет граничные петли как ...

Ребро не имеет объема или массы и всегда обрабатывается так, как будто свойство isDynamic равно false. Края могут сталкиваться только с физическими телами, основанными на объеме.

изменение вашего физического тела на это работает

currentLineNode.physicsBody = SKPhysicsBody(rectangleOf: currentLineNode.frame.size, center: CGPoint(x: startPoint.x + currentLineNode.frame.size.width / 2, y: startPoint.y + currentLineNode.frame.size.height / 2)) 

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

0 голосов
/ 09 мая 2018

Вы используете 2 тела на основе ребер. Основанные на краях тела всегда будут isDynamic = false независимо от того, установлен он или нет. Вам нужен как минимум 1 объем на основе тела, чтобы иметь возможность выполнить контакт.

Плюс ко всему, вы постоянно удаляете и добавляете узел, что является ужасной идеей.

Я бы порекомендовал добавить ваш узел только для touchesBegan, а затем обновить только путь для touchesMoved

...