如何防止用户按下多个键 Javafx?
How to prevent user pressing multiple keys Javafx?
我有一个可以在按下箭头键时移动的播放器。我想防止用户同时按下多个箭头。
这是我尝试过的:
boolean[] pressedKeys = new boolean[4];
canvas.setOnKeyPressed(event -> {
if (!Arrays.asList(pressedKeys).contains(true)){
if (event.getCode() == KeyCode.UP){
pressedKeys[0] = true;
} else if (event.getCode() == KeyCode.RIGHT){
pressedKeys[1] = true;
} else if (event.getCode() == KeyCode.DOWN){
pressedKeys[2] = true;
} else if (event.getCode() == KeyCode.LEFT){
pressedKeys[3] = true;
}
}
});
canvas.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.UP){
pressedKeys[0] = false;
} else if (event.getCode() == KeyCode.RIGHT){
pressedKeys[1] = false;
} else if (event.getCode() == KeyCode.DOWN){
pressedKeys[2] = false;
} else if (event.getCode() == KeyCode.LEFT){
pressedKeys[3] = false;
}
});
但是不行,这里我还是可以按向右和向上的箭头。
感谢您的帮助
感谢@kleopatra
,我找到了解决方案
这是我做的:
boolean pressedKeys = false, releasedKeys = true;
canvas.setOnKeyPressed(event -> {
if (releasedKeys){
// Code goes here
pressedKeys = true;
releasedKeys = false;
}
});
canvas.setOnKeyReleased(event -> {
if (pressedKeys){
pressedKeys = false;
releasedKeys = true;
}
});
像这样,不能一次按多个键
我会像这样创建一个事件处理程序实现:
class InputHandler implements EventHandler<KeyEvent> {
final private Set<KeyCode> activeKeys = new HashSet<>();
@Override
public void handle(KeyEvent event) {
if (activeKeys.isEmpty() && KeyEvent.KEY_PRESSED.equals(event.getEventType())) {
activeKeys.add(event.getCode());
} else if (KeyEvent.KEY_RELEASED.equals(event.getEventType())) {
activeKeys.remove(event.getCode());
}
}
public Set<KeyCode> getActiveKeys() {
return Collections.unmodifiableSet(activeKeys);
}
}
检查 activeKeys.isEmpty()
确保我们不会注册新的按键,直到先前的按键被释放。
可以使用 activeKey 的单个值而不是 activeKeys HashSet,我只是从适用于更一般情况的先前解决方案中改编了它。
使用方法:
InputHandler inputHandler = new InputHandler();
scene.setOnKeyPressed(inputHandler);
scene.setOnKeyReleased(inputHandler);
然后,如果它类似于游戏,在 AnimationTimer 的每个帧更新时检查输入,在更新方法中,您可以检查帧的当前活动键并操作它们,如下所示:
private AnimationTimer createGameLoop() {
return new AnimationTimer() {
public void handle(long now) {
update(now, inputHandler.getActiveKeys());
if (isGameOver()) {
this.stop();
}
}
};
我不确定您选择的策略是否会带来理想的用户体验,您需要尝试一下,看看它在您的应用程序中的效果如何。
我有一个可以在按下箭头键时移动的播放器。我想防止用户同时按下多个箭头。 这是我尝试过的:
boolean[] pressedKeys = new boolean[4];
canvas.setOnKeyPressed(event -> {
if (!Arrays.asList(pressedKeys).contains(true)){
if (event.getCode() == KeyCode.UP){
pressedKeys[0] = true;
} else if (event.getCode() == KeyCode.RIGHT){
pressedKeys[1] = true;
} else if (event.getCode() == KeyCode.DOWN){
pressedKeys[2] = true;
} else if (event.getCode() == KeyCode.LEFT){
pressedKeys[3] = true;
}
}
});
canvas.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.UP){
pressedKeys[0] = false;
} else if (event.getCode() == KeyCode.RIGHT){
pressedKeys[1] = false;
} else if (event.getCode() == KeyCode.DOWN){
pressedKeys[2] = false;
} else if (event.getCode() == KeyCode.LEFT){
pressedKeys[3] = false;
}
});
但是不行,这里我还是可以按向右和向上的箭头。
感谢您的帮助
感谢@kleopatra
,我找到了解决方案
这是我做的:
boolean pressedKeys = false, releasedKeys = true;
canvas.setOnKeyPressed(event -> {
if (releasedKeys){
// Code goes here
pressedKeys = true;
releasedKeys = false;
}
});
canvas.setOnKeyReleased(event -> {
if (pressedKeys){
pressedKeys = false;
releasedKeys = true;
}
});
像这样,不能一次按多个键
我会像这样创建一个事件处理程序实现:
class InputHandler implements EventHandler<KeyEvent> {
final private Set<KeyCode> activeKeys = new HashSet<>();
@Override
public void handle(KeyEvent event) {
if (activeKeys.isEmpty() && KeyEvent.KEY_PRESSED.equals(event.getEventType())) {
activeKeys.add(event.getCode());
} else if (KeyEvent.KEY_RELEASED.equals(event.getEventType())) {
activeKeys.remove(event.getCode());
}
}
public Set<KeyCode> getActiveKeys() {
return Collections.unmodifiableSet(activeKeys);
}
}
检查 activeKeys.isEmpty()
确保我们不会注册新的按键,直到先前的按键被释放。
可以使用 activeKey 的单个值而不是 activeKeys HashSet,我只是从适用于更一般情况的先前解决方案中改编了它。
使用方法:
InputHandler inputHandler = new InputHandler();
scene.setOnKeyPressed(inputHandler);
scene.setOnKeyReleased(inputHandler);
然后,如果它类似于游戏,在 AnimationTimer 的每个帧更新时检查输入,在更新方法中,您可以检查帧的当前活动键并操作它们,如下所示:
private AnimationTimer createGameLoop() {
return new AnimationTimer() {
public void handle(long now) {
update(now, inputHandler.getActiveKeys());
if (isGameOver()) {
this.stop();
}
}
};
我不确定您选择的策略是否会带来理想的用户体验,您需要尝试一下,看看它在您的应用程序中的效果如何。