Spritekit - как настроить столкновения между двумя объектами, чтобы они вели себя как бильярдные шары?

Я пытаюсь создать игру в бильярд с помощью SpriteKit, но у меня возникла проблема, когда дело доходит до физической части. Я пытаюсь настроить его таким образом, чтобы, когда мяч ударяется о другой мяч, ударяемый мяч отскакивал и в конечном итоге замедлялся и останавливался, как в бильярде. Я использую файл .sks, и все три мяча имеют тип тела ограничивающего круга с их трением, лин. демпфирование и угл. для демпфирования установлено значение 0. Для восстановления установлено значение 1. На данный момент, когда к мячу прикасаются, он движется невероятно медленно, а когда два мяча ударяются друг о друга, они просто скользят друг по другу. Как будто скорости нет. Это мой код до сих пор:

   let blueBallName = "blueBall"
    let orangeBallName = "orangeBall"
    let pokeBallName = "pokeBall"

    let blueBallCategory : UInt32 = 0x1 << 0
    let orangeBallCategory : UInt32 = 0x1 << 1
    let pokeBallCategory : UInt32 = 0x1 << 2
    let borderCategory : UInt32 = 0x1 << 3


    class PoolScene: SKScene, SKPhysicsContactDelegate {

      var ballPoke : SKSpriteNode?
      var ballBlue : SKSpriteNode?
      var ballOrange : SKSpriteNode?

      var isFingerOnBlueBall = false


      override func didMove(to view: SKView) {

        let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        borderBody.friction = 0
        self.physicsBody = borderBody

        self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
        physicsWorld.contactDelegate = self

        ballBlue = childNode(withName: blueBallName) as? SKSpriteNode
        ballOrange = childNode(withName: orangeBallName) as? SKSpriteNode
        ballPoke = childNode(withName: pokeBallName) as? SKSpriteNode


        ballBlue?.physicsBody?.categoryBitMask = blueBallCategory
        ballOrange?.physicsBody?.categoryBitMask = orangeBallCategory
        ballPoke?.physicsBody?.categoryBitMask = pokeBallCategory
        borderBody.categoryBitMask = borderCategory


      }

      //Determines which ball user is touching
      override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        let touch = touches.first
    let touchLocation = touch!.location(in: self)

    if let body = physicsWorld.body(at: touchLocation) {
      if body.node!.name == blueBallName {
        print("Blue ball touched")
        isFingerOnBlueBall = true

        let dragBallAction = SKAction.move(to: CGPoint(x: touchLocation.x, y: touchLocation.y), duration: 0.5)

        ballBlue?.run(dragBallAction)


      }
    }
  }
      }

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

            isFingerOnBlueBall = false

          }

      func didBegin(_ contact: SKPhysicsContact) {
        // 1.
        var firstBody: SKPhysicsBody
        var secondBody: SKPhysicsBody
        // 2.
        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
          firstBody = contact.bodyA
          secondBody = contact.bodyB
        } else {
          firstBody = contact.bodyB
          secondBody = contact.bodyA
        }
        // 3.
        if firstBody.categoryBitMask == blueBallCategory && secondBody.categoryBitMask == orangeBallCategory {
          print("Hit Orange ball. First contact has been made.")
        }
      }
    }

person SwiftyJD    schedule 23.09.2016    source источник
comment
Возможный дубликат Как сделать бильярд похожим на физику в SpriteKit?   -  person Nik    schedule 24.09.2016
comment
Да, я пробовал ответы на этот вопрос, но они не сработали.   -  person SwiftyJD    schedule 24.09.2016


Ответы (1)


Действие, которое вы выполняете, — это просто действие MoveTo, поэтому ваш спрайт будет просто пытаться перемещаться туда постоянно. Попробуйте применить силу SKAction, это приложит силу к мячу в том направлении, в котором вы хотите, чтобы он двигался, но не «заставит» его двигаться в определенное место в вашей сцене, физический движок должен позаботиться об остальном. . Кроме того, я не вижу, чтобы вы устанавливали битовые маски столкновения для любого из ваших шаров, если вы хотите, чтобы они сталкивались друг с другом, вы должны установить, например, blueBall.collisionBitMask = OrangeBallCategory и наоборот, хотя это может не быть необходимым для чего-то простого как это еще так что он может работать без него.

person DreamerNo56    schedule 24.09.2016