我有一个可以攻击的游戏。当按下空格键时,武器向下移动,当它被释放时它应该向上移动。
问题是在(某些)UNIX 系统上,KeyReleased 事件也会在按住键时触发。我正在使用 BitSet 来跟踪按下了哪些键,但是由于 KeyReleased 一直在发射,所以武器在我的 Ubuntu 机器上快速上下移动。
我可以同时和我的两个角色一起移动,但是在按下空格键时我不能按住武器。
(按住键几秒钟真正发生的是:keyPressed - keyReleased - keyPressed - keyReleased - keyPressed - keyReleased - ....)
这是 System.out 发生的情况,在每个操作之前都有 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 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);
我已经阅读了有关这种情况的多个主题,但无法使其正常工作。
提前致谢