我正在尝试在Swift中进行跳跃和运行游戏,但遇到了两个主要问题。

首先是我将重力应用于GameScene,但是每次我跳时,玩家都会穿过地板而不是停在其原始位置。我尝试在跳跃前将dynamic = false设置为true,然后在跳跃后将其设置为true,但是它仍然掉在地上。

我遇到的另一个问题是,单击时播放器会应用并推动每次单击,因此会导致跳跃,两次跳跃,三次跳跃等。我似乎无法弄清楚如何使其仅在地面上跳跃。

这是代码。

   override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    //basically my tap to start feature. i set the player's dynamic to false at the play screen, then on the first tap it runs the game, then every other tap it normally jumps
    if player.physicsBody!.dynamic {
        player.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 5.0))
    } else {
    spawnBarrels()
    addTimer()
    runScore()
    startLabel.removeFromParent()
    player.physicsBody?.dynamic = true
    player.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 4.0))
    }
}
 func addGround(){
    //adds the ground
    addChild(ground)
    ground.size = CGSize(width: size.width * 1, height: size.height * 0.1)
    ground.position = CGPoint(x: size.width * 0.5, y: size.height * 0.05)

    ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: size.height, height: size.height * 0.1))

    ground.physicsBody?.dynamic = false
}

var canJump = true
//change

func didBeginContactGround(contact: SKPhysicsContact){
    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
    switch(contactMask){
    case PhysicsCategory.Player | PhysicsCategory.Ground:
        canJump = true
    default:
        return
    }
}

最佳答案

对于问题的第一部分:
您混合了碰撞,接触和类别位掩码。这些是它们的定义/用途:

  • 类别:它是什么类型的对象(PhysicsCategory.Player)
  • 冲突:它与(PhysicsCategory.Ground)
  • 碰撞的对象
  • 联系:游戏应测试碰撞的目的。然后,您可以在以下位置引用两个对象的碰撞:func didBeginContact(contact: SKPhysicsContact){}

  • 现在,您要告诉您的播放器检查它与其他播放器之间的碰撞,并且什么都不碰撞(如果这样做没有意义,我建议您进一步研究这些位掩码)。如果您希望玩家在与障碍物接触时死亡,可以将其Contact设置为PhysicsCategory.Obstacle

    对于第二部分:可以将接触位掩码设置为PhysicsCategory.Ground,如果您还想要障碍物,则可以设置为:PhysicsCategory.Ground | PhysicsCategory.Obstacle。然后,您可以创建一个名为canJump的布尔值,并且仅当它是true时才允许跳转。

    然后,您可以将其写在代码中的某个位置:
    func didBeginContact(contact: SKPhysicsContact) {
        let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
        switch(contactMask) {
        case PhysicsCategory.Player | PhysicsCategory.Ground:
            canJump = true;
        default:
            return
        }
    }
    

    然后,只要您的播放器跳跃,请将canJump设置为false。这样一来,当玩家撞到地面时,他们便可以再次跳跃。如果您想更加精确,则不要在跳跃后将canJump设置为false,而是在玩家不再与地面接触后将其设置为false,方法是使用另一个相同的功能,但将名称更改为didEndContact,然后将其设置为false而不是true

    另外,对于播放器,dynamic应该始终是true。如果您不了解不同的位掩码,则以下链接应该会有所帮助:

    https://www.hackingwithswift.com/read/26/2/loading-a-level-categorybitmask-collisionbitmask-contacttestbitm

    关于ios - 如何在 swift 使用物理方法并使用applyImpulse跳跃一次时设置地面位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35343007/

    10-11 14:23