2015-12-21 45 views
2

我正在为Spritekit写OSX游戏。如何检查一个键是否被按下?考虑这个例子:如何检测OS X上是否按下了某个键?

//some code. this could be e.g. inside a game loop 

if (/*is key 'w' pressed*/) { 
    // move forward 
} 

//some more code 

Swift和Objective-C解决方案都很有用。

注意:我不感兴趣接收或处理该事件,所以我想尽量避免这种情况。我只需要检查一个特定的键是否被按下。

注意事项#2:此问题不是链接问题的重复,因为它仅从接收'keyPressed'事件(作为方法调用的参数)的角度解决问题,而不是从在其他地方进行检查以确定当前是否正按下按键的视角。换句话说,它不能帮助我填写上述if语句中的条件。

我想我可能不得不最终维护一个布尔值数组,每个keycode一个,并更新其内容,因为我收到keyDown和keyUp事件。但我希望能有一个更优雅的解决方案,因为这看起来非常简单。

回答

3

尝试这样的:

正如我已经提到的,你需要addLocalMonitorForEventsMatchingMask添加到您的游戏场景方法didMoveToView用于在keyUp和的keyDown事件,并添加一个switch语句键代码事件:

import SpriteKit 

class GameScene: SKScene { 

    let sprite = SKSpriteNode(imageNamed:"Spaceship") 

    var keyDownState:[String:Bool] = ["k":false, "j":false] 
    var movingLeft = false 
    var movingRight = false 

    override func didMoveToView(view: SKView) { 

     sprite.position = CGPoint(x: view.scene!.frame.midX, y: view.scene!.frame.midY) 
     sprite.setScale(0.5) 
     addChild(sprite) 

     NSEvent.addLocalMonitorForEventsMatchingMask(.KeyDownMask) { (theEvent) -> NSEvent! in 
      print("keyDown event") 
      switch theEvent.keyCode { 
      case 38: 
       print("j is down") 
       self.keyDownState["j"] = true 
      case 40: 
       print("k is down") 
       self.keyDownState["k"] = true 
      default: 
       print("unknown key") 
      } 
      print(self.keyDownState.description) 
      // j and k are pressed 
      if self.keyDownState["j"]! && self.keyDownState["k"]! { 
       self.sprite.removeAllActions() 
       view.scene?.backgroundColor = NSColor.init(red: 1, green: 1, blue: 0, alpha: 1) 
      } 
      // j is pressed 
      if self.keyDownState["j"]! && !self.keyDownState["k"]! { 
       view.scene?.backgroundColor = NSColor.greenColor() 
       if !self.movingLeft { 
        self.sprite.removeActionForKey("moveSpriteRight") 
        self.movingRight = false 
        let moveSpriteLeft = SKAction.moveByX(-50, y: 0, duration: 0.1) 
        self.sprite.runAction(SKAction.repeatActionForever(moveSpriteLeft) , withKey: "moveSpriteLeft") 
        self.movingLeft = true 
       } 
      } 
      // k is pressed 
      if !self.keyDownState["j"]! && self.keyDownState["k"]! { 
       view.scene?.backgroundColor = NSColor.redColor() 
       if !self.movingRight { 
        self.sprite.removeActionForKey("moveSpriteLeft") 
        self.movingLeft = false 
        let moveSpriteRight = SKAction.moveByX(50, y: 0, duration: 0.1) 
        self.sprite.runAction(SKAction.repeatActionForever(moveSpriteRight) , withKey: "moveSpriteRight") 
        self.movingRight = true 
       } 
      } 
      return theEvent 
     } 

     NSEvent.addLocalMonitorForEventsMatchingMask(.KeyUpMask) { (theEvent) -> NSEvent! in 
      print("keyUp event \(theEvent.keyCode)") 
      switch theEvent.keyCode { 
      case 38: 
       print("j is up") 
       self.keyDownState["j"] = false 
       self.movingLeft = false 
      case 40: 
       print("k is up") 
       self.keyDownState["k"] = false 
       self.movingRight = false 

      default: 
       print("unknown key") 
      } 
      print(self.keyDownState.description) 
      if self.keyDownState["j"]! && !self.keyDownState["k"]! { 
       view.scene?.backgroundColor = NSColor.greenColor() 
        self.sprite.removeActionForKey("moveSpriteRight") 
        self.movingRight = false 
        let moveSpriteLeft = SKAction.moveByX(-50, y: 0, duration: 0.1) 
        self.sprite.runAction(SKAction.repeatActionForever(moveSpriteLeft) , withKey: "moveSpriteLeft") 
        self.movingLeft = true 

      } 
      if !self.keyDownState["j"]! && self.keyDownState["k"]! { 
       view.scene?.backgroundColor = NSColor.redColor() 
        self.sprite.removeActionForKey("moveSpriteLeft") 
        self.movingLeft = false 
        let moveSpriteRight = SKAction.moveByX(50, y: 0, duration: 0.1) 
        self.sprite.runAction(SKAction.repeatActionForever(moveSpriteRight) , withKey: "moveSpriteRight") 
        self.movingRight = true 
      } 
      if !self.keyDownState["j"]! && !self.keyDownState["k"]! { 
       self.sprite.removeAllActions() 
       view.scene?.backgroundColor = NSColor(red: 0.72628, green: 0.726298 , blue: 0.726288, alpha: 1) 
      } 
      return theEvent 
     } 
    } 

    override func mouseDown(theEvent: NSEvent) { 
     /* Called when a mouse click occurs */ 

    } 

    override func update(currentTime: CFTimeInterval) { 
     /* Called before each frame is rendered */ 
    } 
} 

Sample project

0

我知道这是旧的,但问题是非常普遍的,其他答案并不真正解决问题的方式问问题的方式,即通过问系统的键盘状态,而不是改变事件。

SFML已经解决了这个问题。检查the code,特别是HIDInputManager类。顺便说一句,我发现苹果公司的IOKit文档没有帮助。

在编写游戏时,我建议依靠SFML或类似的框架,而不是自己解决这个和其他低级别的问题。此外,您可以免费获得跨平台解决方案。

相关问题