【问题标题】:Sticking Node to another Node when Colliding碰撞时将节点粘在另一个节点上
【发布时间】:2015-01-21 13:07:54
【问题描述】:

我正在制作 iOS 游戏(swift xcode)。

有一辆不断移动的汽车(SKAction)和一个你可以通过滑动手势移动的玩家。

一切都好,但现在我想要如果玩家触摸汽车,它会和汽车一样移动(它会粘在汽车上)

现在我该怎么做?

我尝试了很多东西,但没有一个能顺利运行..

我尝试使用

if (CGRectIntersectsRect(car.frame, player.frame)) {
car.position = player.position
}

这行得通,但玩家被踢到车中间,我不想要这个。 我想要的是,如果玩家接触到车底,它就会粘在车底上。

我该怎么做??

对于碰撞检测我也尝试使用:

 func didBeginContact(contact: SKPhysicsContact!) {
    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
    }


    if((firstBody.categoryBitMask & CarCategory) != 0 && (secondBody.categoryBitMask & playerCategory) != 0)
    {


    }

}

但我不知道在括号之间放什么才能让它像我想要的那样顺利运行。

【问题讨论】:

  • 你为什么不使用精灵套件的内置碰撞检测?
  • 你的意思是didbegincontact吗? (见编辑)
  • 是的。请参阅我的答案以了解更多详细信息。

标签: xcode swift sprite-kit collision-detection collision


【解决方案1】:

您可以使用固定的物理关节连接两个节点。物理关节通常连接场景中的两个物理实体。固定版本SKPhysicsJointFixed 将两个主体连接起来,使它们作为一个主体。

这是一个如何用固定关节连接两个物理体的示例:

首先,将其添加到您的 SKScene 子类(例如,GameScene.m)

func joinPhysicsBodies(bodyA:SKPhysicsBody, bodyB:SKPhysicsBody, point:CGPoint) {
    let joint = SKPhysicsJointFixed.jointWithBodyA(bodyA, bodyB: bodyB, anchor: point)
    self.physicsWorld.addJoint(joint)
}

并将其添加到didBeginContact 的if 语句中

self.joinPhysicsBodies(firstBody, bodyB:secondBody, point:contact.contactPoint)

其中contact.contactPoint 是联系人。

【讨论】:

    【解决方案2】:

    不使用物理的更简单的方法是使用constraints:

    if (CGRectIntersectsRect(car.frame, player.frame)) {
        player.constraints=[SKConstraint.distance(SKRange(upperLimit: 100), toNode: car)]
    }
    

    这将确保玩家与汽车的距离最多为 100 点(您可以更改此数字以使其更真实)

    当你想分离播放器时:

    player.constraints=[]
    

    【讨论】:

      【解决方案3】:

      实现 SKPhysicsContactDelegate 协议:

      class GameScene: SKScene, SKPhysicsContactDelegate
      

      在 didMoveToView 结束时设置委托

      override func didMoveToView(view: SKView) {
        ...
      
        self.physicsWorld.contactDelegate = self
      }
      

      创建全局变量来存储碰撞类别:

      let collisionCar: UInt32  = 0x1 << 0
      let collisionPlayer: UInt32    = 0x1 << 1
      

      为汽车和玩家创建物理实体:

      car.physicsBody = SKPhysicsBody(rectangleOfSize: car.size)
      car.physicsBody?.affectedByGravity = false
      car.physicsBody?.dynamic = false
      car.physicsBody?.categoryBitMask = collisionCar
      car.physicsBody?.contactTestBitMask = collisionPlayer
      car.physicsBody?.collisionBitMask = 0x0;
      
      player.physicsBody = SKPhysicsBody(rectangleOfSize: player.size)
      player.physicsBody?.affectedByGravity = false
      player.physicsBody?.dynamic = false
      player.physicsBody?.categoryBitMask = collisionPlayer
      player.physicsBody?.contactTestBitMask = collisionCar
      player.physicsBody?.collisionBitMask = 0x0;
      

      实施 didBeginContact:

          func didBeginContact(contact: SKPhysicsContact) {
      ...
          }
      

      【讨论】:

      • 是的,谢谢,我已经有了,但我不知道在 didbegincontact 中添加什么功能才能让它像我想要的那样粘住。你能帮我解决这个问题吗?
      • 好的。对不起,我没有读过。在这种情况下,您可以使用 SKConstraints 来实现以下行为。我在博客中写了一个小教程。也许这有帮助:stefansdevplayground.blogspot.de/2014/09/…
      • 有更简单的方法吗?我试过你的方法,但它不能像我想要的那样工作,我怎样才能防止跟随者在跟随时旋转?
      • 也许吧。但我目前没有其他想法。
      【解决方案4】:

      有两种方法可以做到这一点。

      你可以使用关节,详见这里How to create joints in Sprite Kit (Xcode)?

      或者您可以从世界中删除玩家节点并将其添加为车辆节点的子节点,在这种情况下,车辆节点和玩家节点将被链接并一起移动。使用removeChildWithName() 和addChild() 执行此操作。

      【讨论】:

      • car.addChild(player) 喜欢这样吗?当我这样做时,它的移动相同但位置不同,我不知道为什么,我尝试使用 player.position = CGPointMake() 进行更改,但由于某种原因不起作用??
      • “职位不同”是什么意思?我假设您希望玩家被汽车“击中”并在汽车行驶时坐在引擎盖上,对吗?将玩家添加为孩子将使玩家保持在被汽车撞到的相同位置。
      • 当你设置播放器的位置时,它会相对于父级设置它。所以你需要记住,它不再是相对于世界,而是相对于汽车。
      • 是的,但是汽车是在 x.position = 50 处添加的,当我将玩家添加为汽车的孩子时,玩家会从汽车的 position.x = 50 处添加..
      • 正如我刚才所说,播放器将相对于汽车放置。
      猜你喜欢
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-10
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 2018-11-21
      相关资源
      最近更新 更多