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

键盘作为游戏控制器,在Swift中处理多个键,swift,macos,sprite-kit,keyboard-events,gamecontroller,Swift,Macos,Sprite Kit,Keyboard Events,Gamecontroller,我正试着用键盘让飞船在屏幕上移动。我设法处理关键事件,但我注意到,当同时按下多个键时,它的行为将不正确,只有一个键具有优先级。我使用的是switch语句,因为我认为keyDown函数对每个键都调用了一次,但即使在这种情况下显式添加fallthrough,也不会更好。有没有人经历过类似的事情?有没有更好的方法将键盘用作控制器 override func keyDown(with event: NSEvent) { switch event.keyCode { case 0

我正试着用键盘让飞船在屏幕上移动。我设法处理关键事件,但我注意到,当同时按下多个键时,它的行为将不正确,只有一个键具有优先级。我使用的是
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)")
      }
   }

我的猜测是,即使你让代码完全按照你描述的方式工作,在实践中,玩你的游戏的人在同一时间敲打两个键也是极其困难的。一个键几乎总是在另一个键之前轻轻敲击。因此,也许您可以实现它,以便捕获一个按键事件,然后在第一个按键事件之后的短时间窗口内(在第一个按键被释放之前)查找第二个按键事件。

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

在测试了一些东西以确保我的SKActions不是问题的原因之后,我想起了我用DelphiX和GLScene在Delphi中编写代码时的一些事情。我知道这是个人电脑,但它是相关的

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

这就是为什么您需要一种跟踪按键状态的方法,这样您就可以检查在任何给定时刻是否同时按下了多个按键


这也是为什么我要构建我的键盘管理器类。

事实上,当你按下键盘键时,问题才会出现。我使用向上和向下键向节点应用脉冲,使用左箭头和右箭头应用角度脉冲。所以你需要按住按键来控制飞船(就像“子空间/连续体”)。虽然使用了一个漏洞,但它仍然表现得很奇怪。事实上,我开始认为我应该建立一个密钥管理器来跟踪密钥的状态,并在其中设置一个更新周期。然后仅使用键盘事件处理程序切换管理器的键状态,或者简单地将键盘管理器转换为委托。。。差不多吧,我会朝那个方向调查的。有没有办法异步检查某个地方内置的密钥状态?我不知道。我从来都不需要异步操作,我做了进一步的测试,我确实需要一些事件以外的方法来管理键盘。我将发布一个带有解释的答案,并继续使用我的键盘管理器。将一个简单的键状态管理器放在一起,它现在可以完美地工作了!如果有人想要代码,让我知道,我会把它放在GitHub上