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
}
}