You're not supposed to abuse keyboard repeat in order to run code repeatedly when a key is held. Instead, keep track yourself of which keys are pressed yourself using keyDown
and keyUp
.
The easiest way to do this is with instance variables:
var leftPressed = false
var rightPressed = false
var upPressed = false
var downPressed = false
You can also use an enum
, an array of key codes, or whatever works best for your app.
In keyDown
and keyUp
, set or clear the key pressed flags. You can make these functions much more concise using a switch
/case
, and if you import Carbon.HIToolbox
, you'll have some constants available for the virtual key codes:
override func keyDown(with event: NSEvent) {
switch Int(event.keyCode) {
case kVK_LeftArrow:
leftPressed = true
case kVK_RightArrow:
rightPressed = true
case kVK_UpArrow:
upPressed = true
case kVK_DownArrow:
downPressed = true
default:
break
}
}
override func keyUp(with event: NSEvent) {
switch Int(event.keyCode) {
case kVK_LeftArrow:
leftPressed = false
case kVK_RightArrow:
rightPressed = false
case kVK_UpArrow:
upPressed = false
case kVK_DownArrow:
downPressed = false
default:
break
}
}
Then, update the player's position in your update
method:
var lastUpdate: TimeInterval!
func update(currentTime: TimeInterval) {
defer { lastUpdate = currentTime }
guard lastUpdate != nil else {
return
}
let dt = currentTime - lastUpdate
guard dt < 1 else {
return //so nothing "jumps" when the the game is unpaused
}
if leftPressed {
player.position.x -= 10 * dt
}
if rightPressed {
player.position.x += 10 * dt
}
if upPressed {
player.position.y -= 10 * dt
}
if downPressed {
player.position.y += 10 * dt
}
}