mac Swift 多个 keyDown 事件
mac Swift multiple keyDown events
我正在 swift 中为 Mac OSX 创建一个 2D 基于图块的平台游戏。当一次按下多个键时,我遇到过控件问题。例如;如果 'D' 让角色向右移动, 'W' 让他跳跃;如果我按住'D'让角色变成运行,然后点击'W'让他跳起来,他落地后就会停下来。他继续向右移动的唯一方法是再次修饰'D',这当然是不可取的。看起来好像在按下 'W' 键时,它取消了 'D' keyDown 事件。如果有人对我如何做到这一点有任何建议,以便可以在不取消其他类似事件的情况下按下多个键,我肯定会很感激。
这是我的 KeyDown 事件的样子:
func returnChar(theEvent: NSEvent!) -> Character?{
let s: String = theEvent.characters!
for char in s {
return char}
return nil
}
override func keyDown(theEvent: NSEvent) {
let s: String = String(self.returnChar(theEvent)!)
switch(s){
case "w":
player.jump()
case "s":
// nothing yet
case "d":
player.moveLeftOrRight(CGVector(dx: 1.0, dy: 0.0))
case "a":
player.moveLeftOrRight(CGVector(dx: -1.0, dy: 0.0))
default:
println("default")
}
}
按下某个键时发生的重复按键事件是由键盘硬件生成的。在 PC 上,协议定义为:
If you press a key, its make code is sent to the computer. When you press and hold down a key, that key becomes typematic, which means the keyboard will keep sending that key's make code until the key is released or another key is pressed. To verify this, open a text editor and hold down the "A" key. ... Typematic data is not buffered within the keyboard. In the case where more than one key is held down, only the last key pressed becomes typematic. Typematic repeat then stops when that key is released, even though other keys may be held down.
由于 PC 和 Mac 都可以使用相同的 USB 键盘(模数一些键重映射),我很确定它们都使用相同的协议。
在您描述的情况下,出现问题是因为即使您按住 D
,当您按下 W
时,键盘也会停止重复 D
键。事件顺序是:
Keydown D
Keydown D
...
Keydown W
Keyup W
此时键盘事件停止。注意 Keyup D
没有发生,所以你实际上知道 D
键仍然按下,但现在由你来模拟重复按键。
我建议您研究如何在键盘硬件中完全禁用自动重复(或忽略按键重复事件)并自己生成所需的游戏行为。您可以通过使用 Keydown
和 Keyup
事件跟踪每个键的状态来轻松做到这一点,忽略重复的 Keydown
.
吉姆·加里森的回答似乎是正确的。在这种情况下的解决方法是,当您按下 D 键时让角色向右移动,并使用循环继续向右移动直到 D 键被释放,您可以使用 func keyUp(theEvent: NSEvent) 检查
如果使用 SpritKit,您可以在更新方法中进行角色移动,同时使用在 keyDown 和 keyUp 方法中设置的 bool。
我正在 swift 中为 Mac OSX 创建一个 2D 基于图块的平台游戏。当一次按下多个键时,我遇到过控件问题。例如;如果 'D' 让角色向右移动, 'W' 让他跳跃;如果我按住'D'让角色变成运行,然后点击'W'让他跳起来,他落地后就会停下来。他继续向右移动的唯一方法是再次修饰'D',这当然是不可取的。看起来好像在按下 'W' 键时,它取消了 'D' keyDown 事件。如果有人对我如何做到这一点有任何建议,以便可以在不取消其他类似事件的情况下按下多个键,我肯定会很感激。 这是我的 KeyDown 事件的样子:
func returnChar(theEvent: NSEvent!) -> Character?{
let s: String = theEvent.characters!
for char in s {
return char}
return nil
}
override func keyDown(theEvent: NSEvent) {
let s: String = String(self.returnChar(theEvent)!)
switch(s){
case "w":
player.jump()
case "s":
// nothing yet
case "d":
player.moveLeftOrRight(CGVector(dx: 1.0, dy: 0.0))
case "a":
player.moveLeftOrRight(CGVector(dx: -1.0, dy: 0.0))
default:
println("default")
}
}
按下某个键时发生的重复按键事件是由键盘硬件生成的。在 PC 上,协议定义为:
If you press a key, its make code is sent to the computer. When you press and hold down a key, that key becomes typematic, which means the keyboard will keep sending that key's make code until the key is released or another key is pressed. To verify this, open a text editor and hold down the "A" key. ... Typematic data is not buffered within the keyboard. In the case where more than one key is held down, only the last key pressed becomes typematic. Typematic repeat then stops when that key is released, even though other keys may be held down.
由于 PC 和 Mac 都可以使用相同的 USB 键盘(模数一些键重映射),我很确定它们都使用相同的协议。
在您描述的情况下,出现问题是因为即使您按住 D
,当您按下 W
时,键盘也会停止重复 D
键。事件顺序是:
Keydown D
Keydown D
...
Keydown W
Keyup W
此时键盘事件停止。注意 Keyup D
没有发生,所以你实际上知道 D
键仍然按下,但现在由你来模拟重复按键。
我建议您研究如何在键盘硬件中完全禁用自动重复(或忽略按键重复事件)并自己生成所需的游戏行为。您可以通过使用 Keydown
和 Keyup
事件跟踪每个键的状态来轻松做到这一点,忽略重复的 Keydown
.
吉姆·加里森的回答似乎是正确的。在这种情况下的解决方法是,当您按下 D 键时让角色向右移动,并使用循环继续向右移动直到 D 键被释放,您可以使用 func keyUp(theEvent: NSEvent) 检查
如果使用 SpritKit,您可以在更新方法中进行角色移动,同时使用在 keyDown 和 keyUp 方法中设置的 bool。