SKShapeNode обнаружение столкновений в комплекте Sprite не обнаруживает столкновения - PullRequest
0 голосов
/ 28 января 2019

Я пытаюсь добиться обнаружения коллизий между SKShapeNode (круговым узлом) и SKShapeNode (квадратным узлом), так же, как приложение "Змея VS Blocks".

Ниже приведен мой кодфрагмент создания моего узла

Создание змеи

 private func addSnake() {
        snake = SKShapeNode(circleOfRadius: Constants.snakeRadius)
        snake.fillColor = Constants.snakeColor
        let snakeXPosition = (Helper.getScreenWidth() / 2.0) - Constants.snakeRadius
        snake.position = CGPoint(x: snakeXPosition, y: size.height * 0.3)
        snake.physicsBody = SKPhysicsBody(rectangleOf: snake.frame.size)
        snake.physicsBody?.isDynamic = false
        snake.physicsBody?.categoryBitMask = PhysicsCategory.snake
        snake.physicsBody?.contactTestBitMask = PhysicsCategory.block
        snake.physicsBody?.collisionBitMask = PhysicsCategory.none
        snake.name = "Snake"
        addChild(snake)
    }

Создание блока

func addBlocks() {
    for index in 0...(blockCount-1) {
       let hasBlock = getRandomBool()
        if hasBlock {
            let block = getBlock(for: index)
            block.fillColor = .red
            addChild(block)
            let actionMove = getBlockMoveAction(for: block, atIndex: index)
            let actionMoveDone = SKAction.removeFromParent()
            block.run(SKAction.sequence([actionMove, actionMoveDone]))
        }
    }
}

func getBlockMoveAction(for block: SKShapeNode, atIndex: Int) -> SKAction {
    return SKAction.move(to: CGPoint(x:  CGFloat(atIndex) * width, y: -block.frame.size.height),
                  duration: TimeInterval(blockMovementDuration))
}

func getBlock(for index: Int) -> SKShapeNode {
    let rect = CGRect(x: 0, y: 0, width: width, height: width)
    let block = SKShapeNode(rect: rect, cornerRadius: Constants.blockCornerRadius)
    block.name = "Block"
    block.position = CGPoint(x: CGFloat(index) * width, y: (Helper.getScreenHeight() + width))
    block.physicsBody = SKPhysicsBody(rectangleOf: block.frame.size)
    block.physicsBody?.isDynamic = false
    block.physicsBody?.categoryBitMask = PhysicsCategory.block
    block.physicsBody?.contactTestBitMask = PhysicsCategory.snake
    block.physicsBody?.collisionBitMask = PhysicsCategory.none
    return block
}

func getRandomBool() -> Bool {
    return arc4random_uniform(2) == 0
}

Ниже приведено изображение результата кода выше:

Screenshot of the app

Моя первая проблема, я не знаю почему, но когда я включил skview, чтобы показать физику, view.showsPhysics = true

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

Во-вторых, я также подтвердил контакт с делегатом

physicsWorld.contactDelegate = self

Но мой

didBegin(_ contact: SKPhysicsContact)

не запускается

код обнаружения столкновения:

extension GameScene: SKPhysicsContactDelegate {

func didBegin(_ contact: SKPhysicsContact) {

    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA //snake
        secondBody = contact.bodyB //block
    } else {
        firstBody = contact.bodyB //block
        secondBody = contact.bodyA //snake
    }

    if ((firstBody.categoryBitMask & PhysicsCategory.snake != 0) &&
        (secondBody.categoryBitMask & PhysicsCategory.block != 0)) {
        if let snake = firstBody.node as? SKShapeNode,
            let block = secondBody.node as? SKShapeNode {
            snakeDidCollideWithBlock(snake: snake, block: block)
        }
    }
}

func snakeDidCollideWithBlock(snake: SKShapeNode, block: SKShapeNode) {
    print("Hit")
    block.removeFromParent()

}

}

Я перебирал другие вопросы в stackoverflow, ища похожую проблему, но не нашел никакого решения.

1 Ответ

0 голосов
/ 28 января 2019

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

...