【问题标题】:How Can I get keyboard input in a SpriteKit Game?如何在 SpriteKit 游戏中获得键盘输入?
【发布时间】:2014-05-27 19:17:45
【问题描述】:

我是 SpriteKit 编程的初学者,一直在尝试弄清楚如何处理来自键盘的输入。

到目前为止我发现你应该继承 NSResponder 并像这样实现它:

@interface AppDelegate : NSResponder <NSApplicationDelegate>
-(void)keyUp:(NSEvent *)theEvent;
-(void)keyDown:(NSEvent *)theEvent;
@end

@implementation AppDelegate
-(void)keyUp:(NSEvent *)theEvent
{
   NSLog(@"Key Released");
}
-(void)keyDown:(NSEvent *)theEvent
{
  NSLog(@"Key Pressed");
}
@end

显然,AppDelegate 的接口和实现中还有一些方法/属性,但我没有将它们放在那里以保持问题的相关性。

接下来,我将开始使用键码来检测正在按下哪些键,但 keyUpkeyDown 方法甚至不会被调用。我不知道为什么。

有什么帮助吗?

更新: 感谢您的回答!我发现你必须直接在你的场景类中实现keyUpkeyDown,因为它们不会被 AppDelegate 调用。再次感谢您的帮助!

【问题讨论】:

    标签: objective-c macos sprite-kit


    【解决方案1】:

    我知道的最简单的方法是在您的 SKScene 中实现 keyDown 方法(而不是直接在 AppDelegate 中)。你不必继承任何东西。

    - (void)keyDown:(NSEvent *)event {
        [self handleKeyEvent:event keyDown:YES];
    }
    
    - (void)keyUp:(NSEvent *)event {
        [self handleKeyEvent:event keyDown:NO];
    }
    

    然后使用handleKeyEvent:(NSEvent *)event keyDown:(BOOL)downOrUp的方法来检查哪个键被按下了:

    - (void)handleKeyEvent:(NSEvent *)event keyDown:(BOOL)downOrUp {
        // First check the arrow keys since they are on the numeric keypad.
        if ([event modifierFlags] & NSNumericPadKeyMask) { // arrow keys have this mask
            NSString *theArrow = [event charactersIgnoringModifiers];
            unichar keyChar = 0;
            if ([theArrow length] == 1) {
                keyChar = [theArrow characterAtIndex:0];
                switch (keyChar) {
                    case NSUpArrowFunctionKey:
                        self.defaultPlayer.moveForward = downOrUp;
                        break;
                    case NSLeftArrowFunctionKey:
                        self.defaultPlayer.moveLeft = downOrUp;
                        break;
                    case NSRightArrowFunctionKey:
                        self.defaultPlayer.moveRight = downOrUp;
                        break;
                    case NSDownArrowFunctionKey:
                        self.defaultPlayer.moveBack = downOrUp;
                        break;
                }
            }
        }
    
        // Now check the rest of the keyboard
        NSString *characters = [event characters];
        for (int s = 0; s<[characters length]; s++) {
            unichar character = [characters characterAtIndex:s];
            switch (character) {
                case 'w':
                    self.defaultPlayer.moveForward = downOrUp;
                    break;
                case 'a':
                    self.defaultPlayer.moveLeft = downOrUp;
                    break;
                case 'd':
                    self.defaultPlayer.moveRight = downOrUp;
                    break;
                case 's':
                    self.defaultPlayer.moveBack = downOrUp;
                    break;
                case ' ':
                    self.defaultPlayer.fireAction = downOrUp;
                    break;
            }
        }
    }
    

    我从 Apple SpriteKit Adventure 游戏中获取了这段代码。我发现学习 SpriteKit 非常有用:)

    【讨论】:

      【解决方案2】:

      HeyFara 答案的 Swift (2.0) 版本。我刚刚在您进行实际函数调用的地方弹出了“中断”。

          public override func keyDown(theEvent: NSEvent) {
          handleKeyEvent(theEvent, keyDown: true)
      }
      
      public override func keyUp(theEvent: NSEvent) {
          handleKeyEvent(theEvent, keyDown: false)
      }
      
      public func handleKeyEvent(event:NSEvent, keyDown:Bool){
          if event.modifierFlags.contains(NSEventModifierFlags.NumericPadKeyMask){
              if let theArrow = event.charactersIgnoringModifiers, keyChar = theArrow.unicodeScalars.first?.value{
                  switch Int(keyChar){
                  case NSUpArrowFunctionKey:
                      break
                  case NSDownArrowFunctionKey:
                      break
                  case NSRightArrowFunctionKey:
                      break
                  case NSLeftArrowFunctionKey:
                      break
                  default:
                      break
                  }
              }
          } else {
              if let characters = event.characters{
                  for character in characters.characters{
                      switch(character){
                      case "w":
                          break
                      default:
                          print(character)
                      }
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        如果您想知道何时按下某个键,您应该订阅全局事件管理器。

        [NSEvent addGlobalMonitorForEventsMatchingMask:(NSKeyDownMask) handler:^(NSEvent *event) {
        [NSEvent removeMonitor:event];
        

        这将在任何按键被按下时调用处理程序。

        【讨论】:

          【解决方案4】:

          这是 HeyFara 答案的 rougeExciter 版本,但在 Swift 4.2 中...以防有人在几分钟前找到这个旧帖子...就像我自己一样 :)...

          public override func keyDown(with event: NSEvent) {
              handleKeyEvent(event, keyDown: true)
          }
          
          public override func keyUp(with event: NSEvent) {
              handleKeyEvent(event, keyDown: false)
          }
          
          public func handleKeyEvent(_ event: NSEvent, keyDown: Bool){
              if event.modifierFlags.contains(NSEvent.ModifierFlags.numericPad) {
                  if let theArrow = event.charactersIgnoringModifiers, let keyChar = theArrow.unicodeScalars.first?.value{
                      switch Int(keyChar){
                      case NSUpArrowFunctionKey:
                          break
                      case NSDownArrowFunctionKey:
                          break
                      case NSRightArrowFunctionKey:
                          break
                      case NSLeftArrowFunctionKey:
                          break
                      default:
                          break
                      }
                  }
              } else {
                  if let characters = event.characters{
                      for character in characters {
                          switch(character){
                          case "w":
                              break
                          default:
                              print(character)
                          }
                      }
                  }
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2015-07-28
            • 1970-01-01
            • 2014-05-08
            • 2015-08-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-10-04
            • 1970-01-01
            相关资源
            最近更新 更多