gpt4 book ai didi

java - KeyListener - 忽略按住时释放的键(Ubuntu,...)

转载 作者:行者123 更新时间:2023-12-04 04:57:36 27 4
gpt4 key购买 nike

我有一个游戏,你可以攻击。当按下空格键时,武器向下移动,当它被释放时它应该向上移动。

问题是在(某些)UNIX 系统上,KeyReleased 事件也会在按住键的同时触发。我正在使用 BitSet 来跟踪按下了哪些键,但是由于 KeyReleased 不断发射,武器在我的 Ubuntu 机器上上下移动非常快。

我可以同时移动我的两个角色,但是在按下空格键时我无法放下武器。

(按住键几秒钟真正发生的是:
keyPressed - keyReleased - keyPressed - keyReleased - keyPressed - keyReleased - ....)

这是一个 System.out 发生的事情,在每个 Action 之前都有 System.currentTimeMillis() :

1368696607559 - Pressed
1368696608052 - Released
1368696608053 - Pressed
1368696608082 - Released
1368696608083 - Pressed
1368696608112 - Released
1368696608113 - Pressed
1368696608143 - Released
1368696608144 - Pressed
1368696608173 - Released

我正在使用的代码是:
//Inner Class
private class KeyDispatcher extends KeyAdapter implements ActionListener{

private BitSet keyBits = new BitSet(256);
private Timer timer = new Timer(20, this);
boolean player1Attack = false, player2Attack = false;

public KeyDispatcher(){
timer.start();
}

@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
keyBits.set(keyCode);
}

@Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
keyBits.clear(keyCode);
if(player1Attack && !isKeyPressed(KeyEvent.VK_SPACE)){
controller.stopAttack(0);
player1Attack = false;
}
//player 2
...
}

public boolean isKeyPressed(final int keyCode) {
return keyBits.get(keyCode);
}

@Override
public void actionPerformed(ActionEvent e) {
if(isGameOver()){
timer.stop();
}else{
//player1
if(!player1Attack && isKeyPressed(KeyEvent.VK_RIGHT)){
controller.moveRight(0);
}
if(!player1Attack && isKeyPressed(KeyEvent.VK_UP)){
controller.moveUp(0);
}
if(!player1Attack && isKeyPressed(KeyEvent.VK_DOWN)){
controller.moveDown(0);
}
if(!player1Attack && isKeyPressed(KeyEvent.VK_LEFT)){
controller.moveLeft(0);
}
if(!player1Attack && isKeyPressed(KeyEvent.VK_NUMPAD0)){
controller.attack(0); player1Attack = true; update();
}
//player2
...
}
}

}

我也尝试用 KeyBinding 替换它,因为这些似乎更值得推荐,但这里仍然存在相同的“问题”(释放的 Action 在按下时继续触发)......
    Action attack = new AbstractAction(){

@Override
public void actionPerformed(ActionEvent e) {
controller.attack(0);
}

};
Action stopAttack = new AbstractAction(){

@Override
public void actionPerformed(ActionEvent e) {
controller.stopAttack(0);
}

};
background.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "attack");
background.getActionMap().put("attack", attack);

background.getInputMap().put(KeyStroke.getKeyStroke("released SPACE"), "stopAttack");
background.getActionMap().put("stopAttack", stopAttack);

我已经阅读了关于这种情况的多个主题,但一直无法让它发挥作用。

提前致谢

最佳答案

因此,让我们举一个例子,在其中一台您遇到问题的 UBUNTU 机器中;
假设他们按住键盘按钮 1000 毫秒。

根据您的评论,这就是时间线上会发生的情况:

0 ms         -    10ms         -   1000ms
keyPressed keyReleased keyReleased

因此,在这些有问题的计算机中,您有 1x keyPressed 事件和 2x keyReleased 事件。
第二个 keyReleased 事件,是坏人。

我将执行以下操作来“修补”问题(直到您正确识别这些 UBUNTU 计算机中的差异):

(注意我使用的是系统时间,而不是每秒固定的 MS,因为 KeyEvents 发生在 UI 线程而不是游戏或 OpenGL 线程上)
//This isn't the 10ms of the example, but if this doesn't work, try increasing it a bit further or 
//try meassuring the exact time of the "faulty/not wanted" first onKeyReleased event
final private static long KEY_RELEASE_TIME_LOCK_IN_MS = 100L;
private static long lastKeyRelease_TimeMillis;

@Override
public void keyPressed(KeyEvent e) {

int keyCode = e.getKeyCode();
keyBits.set(keyCode);


}



@Override
public void keyReleased(KeyEvent e) {
final long currentTimeMillis = System.currentTimeMillis();

if( (currentTimeMillis - lastKeyRelease_TimeMillis) <= KEY_RELEASE_TIME_LOCK_IN_MS){
//We just ignored the keyRelease!, we are not allowing keyReleases that fast!
return;
}


int keyCode = e.getKeyCode();
keyBits.clear(keyCode);
if(player1Attack && !isKeyPressed(KeyEvent.VK_SPACE)){
controller.stopAttack(0);
player1Attack = false;
}

lastKeyRelease_TimeMillis = System.currentTimeMillis();

//player 2
...
}


//Rockster., let me know if it worked out

关于java - KeyListener - 忽略按住时释放的键(Ubuntu,...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16574472/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com