2015-12-21 103 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或類似的框架,而不是自己解決這個和其他低級別的問題。此外,您可以免費獲得跨平臺解決方案。