简体   繁体   English

Spritekit-如何在两个对象之间建立碰撞,使其表现得像台球?

[英]Spritekit- how to set up collisions between two objects so they behave like billiard balls?

I'm trying to create a billiards game with SpriteKit but am having a problem when it comes to the physics part of it. 我正在尝试使用SpriteKit创建台球游戏,但涉及到物理部分时遇到了问题。 I'm trying to set it up so when a ball hits another ball the ball being hit bounces off and eventually slows down and stops just like in billiards. 我正在尝试进行设置,以便当一个球击中另一个球时,被击中的球会弹起并最终减速并停止,就像在台球中一样。 I'm using the .sks file and have all three balls using a bounding circle body type with their friction, lin. 我正在使用.sks文件,并且所有三个球都使用边界圆体类型及其摩擦力Lin。 damping and ang. 阻尼和倾角。 damping set to 0. The restitution is set to 1. As of right now when a ball is touched it moves incredibly slow and when two balls hit each other they just kind of slide against each other. 阻尼设置为0。恢复设置为1。到目前为止,当碰到一个球时,它的移动速度非常慢,并且当两个球相互撞击时,它们只是相互滑动。 It's like there is no velocity. 就像没有速度。 This is my code so far: 到目前为止,这是我的代码:

   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.")
        }
      }
    }

The action you're doing is just the MoveTo action so your sprite will just try and move there constantly. 您正在执行的动作只是MoveTo动作,因此您的Sprite只会尝试不断移动。 Try doing the SKAction apply force, this will apply a force to the ball in the direction you want it to move to but will not 'force' it to go to on particular location in your scene, the physics engine should take care of the rest. 尝试执行SKAction施加力,这将沿您想要移动的方向向球施加力,但不会“强制”将球移动到场景中的特定位置,物理引擎应负责其余的工作。 Aside from that, I dont see that you set collision bit masks to any of your balls, if you want them to collide with eachother you should set for example blueBall.collisionBitMask = orangeBallCategory and vice versa, although this may not be necessary for something simple like this yet so it may work without it. 除此之外,我看不到您对任何球都设置了碰撞位掩码,如果希望它们彼此碰撞,则应设置例如blueBall.collisionBitMask = orangeBallCategory,反之亦然,尽管这对于简单的操作可能不是必需的像这样,所以没有它可能会起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM