【问题标题】:Keyboard as game controller, handling multiple keys in Swift键盘作为游戏控制器,在 Swift 中处理多个键
【发布时间】:2017-03-18 21:00:11
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    我的猜测是,即使您的代码完全按照您描述的方式运行,在实践中,任何玩您的游戏的人都很难同时敲击两个键。一个键几乎总是先于另一个键被敲击。因此,也许您可​​以实现它,以便捕获一个关键事件,然后在第一个事件之后(第一个事件发布之前)的短时间内寻找第二个事件发生。

    【讨论】:

    • 嗯,实际上是在您按住按键时出现问题。我使用向上和向下键向我的节点施加脉冲,并使用左右箭头施加角脉冲。所以你需要按住按键来控制飞船(à la "Subspace/Continuum")。使用 fallthrough 有所帮助,但它的行为仍然很奇怪。
    • 实际上我开始认为我应该构建一个密钥管理器来跟踪密钥的状态并在那里放置一个更新周期。然后只使用键盘事件处理程序来切换管理器的键状态,或者只是将键盘管理器变成一个委托......类似的东西。
    【解决方案2】:

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

    【讨论】:

    • 我会朝那个方向调查。有没有办法检查某个地方异步构建的关键状态?
    • 我不知道。我从来不需要异步执行此操作。
    • 好吧,我对它进行了进一步的测试,我确实需要除事件之外的其他方式来管理键盘。我将发布一个带有解释的答案,并继续在我的键盘管理器上工作。
    【解决方案3】:

    在测试了一些东西以确保我的 SKAction 不是问题的原因之后,我想起了我在 Delphi 中使用 DelphiX 和 GLScene 编码时的一些事情。我知道它是 PC,但它是相关的。

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

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

    这也是我要构建键盘管理器类的原因。

    【讨论】:

    • 将一个简单的密钥状态管理器放在一起,它现在可以完美运行!如果有人想要代码,请告诉我,我会把它放在 GitHub 上
    猜你喜欢
    • 1970-01-01
    • 2013-09-10
    • 2015-09-20
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    相关资源
    最近更新 更多