处理多次按键而忽略重复按键
我在另一个问题(> 如何在Java中同时处理按键?)的注释部分提出了这个问题,并被要求提出一个新问题。
我的问题是,当用户按下按键时,当我创建按键列表ArrayList时,不会通过keyReleased事件足够快地将其删除。我希望运动与“
asdf”和北,东,南,西,东北…等保持一致。
这是我的两个事件的代码:
@Overridepublic void keyPressed(KeyEvent e) {
if(chatTextField.isFocusOwner() == true){
//do nothing - don't walk
} else {
logger.debug("Key Pressed: " + e.getKeyChar());
lastKey = keysPressed.get(keysPressed.size()-1);
for (String key : keysPressed){
if (!key.contains(String.valueOf(e.getKeyChar())) && !lastKey.contains(String.valueOf(e.getKeyChar()))){
keysPressed.add(String.valueOf(e.getKeyChar()));
System.out.println("ADDED: " + keysPressed);
}
}
String keysList = keysPressed.toString();
if (keysList.contains("w")){
if (keysList.contains("d")){
requestCharacterMove("NorthEast");
} else if(keysList.contains("a")){
requestCharacterMove("NorthWest");
} else{
requestCharacterMove("North");
}
} else if (keysList.contains("s")){
if (keysList.contains("d")){
requestCharacterMove("SouthEast");
} else if(keysList.contains("a")){
requestCharacterMove("SouthWest");
} else{
requestCharacterMove("South");
}
} else if (keysList.contains("d")){
requestCharacterMove("East");
} else if (keysList.contains("a")){
requestCharacterMove("West");
}
}
}
@Override
public void keyReleased(KeyEvent e) {
if(chatTextField.isFocusOwner() == true){
//do nothing - don't walk
} else {
logger.debug("Key Released: " + e.getKeyChar());
for (String key : keysPressed){
if (key.contains(String.valueOf(e.getKeyChar()))){
keysPressed.remove(String.valueOf(e.getKeyChar()));
System.out.println("REMOVED: " + keysPressed);
}
}
}
}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
直到我通过lastKey(String)变量将第二个检查添加到那里,金字塔创建的数量巨大。即使进行第二次检查,列表也会增加,并且几乎总是有两三份重复。因为我的角色笨拙地移动着,所以对此的任何帮助都会很棒。:(
同样,删除重复转换为char,string,arrayList的任何方法也将非常有用,因为我担心我为“简单”使用了太多类型。
回答:
你obseravtion事情最有可能慢慢地处理造成 仅仅 是众多的System.out.println()语句。
您没有得到对角线移动的问题是由于您的检查逻辑有些错误-而不是显式检查(例如)是否按下了键A 和 B,而是独立地检查它们-键A在一个方向上移动字符,B在另一个方向上移动字符。总计(例如),通过移动WEST 和 NORTH,您将有效地移动NORTHWEST。
除了使用按键列表之外,您还可以使用java.util.BitSet并为每个当前按下的按键设置位。这也应该大大减少您需要编写的代码量(keyPressed只是设置密钥代码指示的位,keyReleased清除它)。要检查是否按下了按键,请询问BitSet,然后询问当前是否设置了代码位。
编辑:使用BitSet而不是列表的示例
public class BitKeys implements KeyListener { private BitSet keyBits = new BitSet(256);
@Override
public void keyPressed(final KeyEvent event) {
int keyCode = event.getKeyCode();
keyBits.set(keyCode);
}
@Override
public void keyReleased(final KeyEvent event) {
int keyCode = event.getKeyCode();
keyBits.clear(keyCode);
}
@Override
public void keyTyped(final KeyEvent event) {
// don't care
}
public boolean isKeyPressed(final int keyCode) {
return keyBits.get(keyCode);
}
}
我使示例实现了KeyListener,因此您甚至可以按原样使用它。当您需要知道是否按下某个键时,请使用isKeyPressed()。您需要确定是喜欢原始密钥代码(就像我一样)还是选择关键字符(就像您当前所做的那样)。无论如何,您将看到使用BitSet类将用于记录密钥的代码量减少到几行:)
以上是 处理多次按键而忽略重复按键 的全部内容, 来源链接: utcz.com/qa/406958.html