键盘作为游戏控制器,处理Swift中的多个键

时间:2017-03-18 21:00:11

标签: swift macos sprite-kit keyboard-events gamecontroller

我正试图用键盘在屏幕上移动太空飞船。我设法处理关键事件,但我注意到当多个键同时保持关闭时,它将无法正常运行,只有一个具有优先权。我正在使用switch语句,因为我认为每个键都调用了keyDown函数一次,但即使我在这些情况下明确添加fallthrough,也不是更好。有没有人经历过这样的事情,有没有更好的方法将键盘用作控制器?

override func keyDown(with event: NSEvent) {

      switch event.keyCode {
      case 0x31:
         if let playerShip = self.playerShip {
            playerShip.run(SKAction.init(named: "Pulse")!, withKey: "fadeInOut")
         }
      case 123:
         if let playerShip = self.playerShip {
            playerShip.run(SKAction.applyAngularImpulse(0.001, duration: 0.1))
         }
      case 124:
         if let playerShip = self.playerShip {
            playerShip.run(SKAction.applyAngularImpulse(-0.001, duration: 0.1))
         }
      case 125:
         if let playerShip = self.playerShip {
            playerShip.run(SKAction.applyImpulse(CGVector.init(angle: playerShip.zRotation).opposite(), duration: 0.1))
         }
      case 126:
         if let playerShip = self.playerShip {
            playerShip.run(SKAction.applyImpulse(CGVector.init(angle: playerShip.zRotation), duration: 0.1))
         }
      default:
         print("keyDown: \(event.characters!) keyCode: \(event.keyCode)")
      }
   }

3 个答案:

答案 0 :(得分:1)

我的猜测是,即使你让代码完全按照你描述的方式工作,实际上对于玩游戏的人来说,在同一时间点击两个键也是非常困难的。一把钥匙几乎总是会在另一把钥匙之前轻微击中。所以,也许你可以实现它,以便捕获一个关键事件,然后在第一个关键事件之后(在第一个关键事件发布之前)的短时间窗口内查找第二个关键事件。

答案 1 :(得分:0)

每次按下某个键时,OS X都应调用keyDown方法。如果按下两个键,它会被调用两次,等等。也许你看到这种行为,因为只有最后一个键的动作才会覆盖第一个键的动作?

答案 2 :(得分:0)

在测试了一些事情以确保我的SKActions不是问题的原因之后,我记得在Delphi使用DelphiX和GLScene编写代码时的一些事情。我知道它是PC,但它是相关的。

问题是键盘事件提示将仅重新触发按下的las键。因此,使用向上箭头施加力并保持按下加速将起作用,直到我按下,例如,向左箭头施加一些扭矩。然后左箭头键将被重新触发,但是即使它现在仍然被按下,下一个来自向上箭头的事件将是您实际释放它时。因此,船舶将开始旋转,但将停止加速,因为向上箭头不会重新触发keyDown事件。

这就是为什么你需要一种方法来跟踪关键状态,这样你就可以检查在任何特定时刻是否按下了多个键。

这也是我要建立我的键盘管理员课程的原因。