好吧,我很抱歉这是一个非常奇怪的问题,但这让我发疯。
我通过以下方式处理游戏的 WASD 移动:
Action ClassWASDKeyPressed = new ClassWASDKeyPressed();
Action ClassWASDKeyReleased = new ClassWASDKeyReleased();
BitKeys movementBitKeys = new BitKeys(); //for WASD movement key pressed/releases
//pressed
theDesktop.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("W"), "wButtonPress");
theDesktop.getActionMap().put("wButtonPress", ClassWASDKeyPressed);
theDesktop.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), "aButtonPress");
theDesktop.getActionMap().put("aButtonPress", ClassWASDKeyPressed);
theDesktop.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "sButtonPress");
theDesktop.getActionMap().put("sButtonPress", ClassWASDKeyPressed);
theDesktop.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"), "dButtonPress");
theDesktop.getActionMap().put("dButtonPress", ClassWASDKeyPressed);
//released
theDesktop.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released W"), "wButtonRelease");
theDesktop.getActionMap().put("wButtonRelease", ClassWASDKeyReleased);
theDesktop.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released A"), "aButtonRelease");
theDesktop.getActionMap().put("aButtonRelease", ClassWASDKeyReleased);
theDesktop.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released S"), "sButtonRelease");
theDesktop.getActionMap().put("sButtonRelease", ClassWASDKeyReleased);
theDesktop.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released D"), "dButtonRelease");
theDesktop.getActionMap().put("dButtonRelease", ClassWASDKeyReleased);
这是两个 Action 类:
class ClassWASDKeyPressed extends AbstractAction {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
if (chatTextField.isFocusOwner() == false){
if (e.getActionCommand().equals("w")){
keyPressed(87);
} else if(e.getActionCommand().equals("a")){
keyPressed(65);
} else if(e.getActionCommand().equals("s")){
keyPressed(83);
} else if(e.getActionCommand().equals("d")){
keyPressed(68);
}
}
}
}
class ClassWASDKeyReleased extends AbstractAction {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
if (chatTextField.isFocusOwner() == false){
if (e.getActionCommand().equals("w")){
keyReleased(87);
} else if(e.getActionCommand().equals("a")){
keyReleased(65);
} else if(e.getActionCommand().equals("s")){
keyReleased(83);
} else if(e.getActionCommand().equals("d")){
keyReleased(68);
}
}
}
}
这是其逻辑:
public void keyPressed(int e) {
long endTime = System.nanoTime();
long elapsedTime = endTime - startTime;
double elapsedTimeSeconds = (double)elapsedTime / 1000000000.0;
if (elapsedTimeSeconds < .125){ //let them move 8 times a second
logger.info("KeyPressed (QUICK): " + elapsedTimeSeconds);
} else {
logger.info("KeyPressed (VALID): " + elapsedTimeSeconds);
//logger.debug("Key Pressed: " + e.getKeyChar()); //FOR TROUBLESHOOTING
movementBitKeys.keyPressed(e);
//movementBitKeys.showKeyList(); //FOR TROUBLESHOOTING
if (movementBitKeys.isKeyPressed(87) && !movementBitKeys.isKeyPressed(68) && !movementBitKeys.isKeyPressed(83) && !movementBitKeys.isKeyPressed(65)){
requestCharacterMove("North");
}
if (movementBitKeys.isKeyPressed(87) && movementBitKeys.isKeyPressed(68) && !movementBitKeys.isKeyPressed(83) && !movementBitKeys.isKeyPressed(65)){
requestCharacterMove("NorthEast");
}
if (movementBitKeys.isKeyPressed(87) && !movementBitKeys.isKeyPressed(68) && !movementBitKeys.isKeyPressed(83) && movementBitKeys.isKeyPressed(65)){
requestCharacterMove("NorthWest");
}
if (!movementBitKeys.isKeyPressed(87) && movementBitKeys.isKeyPressed(68) && !movementBitKeys.isKeyPressed(83) && !movementBitKeys.isKeyPressed(65)){
requestCharacterMove("East");
}
if (!movementBitKeys.isKeyPressed(87) && !movementBitKeys.isKeyPressed(68) && movementBitKeys.isKeyPressed(83) && !movementBitKeys.isKeyPressed(65)){
requestCharacterMove("South");
}
if (!movementBitKeys.isKeyPressed(87) && movementBitKeys.isKeyPressed(68) && movementBitKeys.isKeyPressed(83) && !movementBitKeys.isKeyPressed(65)){
requestCharacterMove("SouthEast");
}
if (!movementBitKeys.isKeyPressed(87) && !movementBitKeys.isKeyPressed(68) && movementBitKeys.isKeyPressed(83) && movementBitKeys.isKeyPressed(65)){
requestCharacterMove("SouthWest");
}
if (!movementBitKeys.isKeyPressed(87) && !movementBitKeys.isKeyPressed(68) && !movementBitKeys.isKeyPressed(83) && movementBitKeys.isKeyPressed(65)){
requestCharacterMove("West");
}
startTime = endTime;
}
}
public void keyReleased(int e) {
//logger.debug("Key Released: " + e.getKeyChar()); //FOR TROUBLESHOOTING
movementBitKeys.keyReleased(e);
//movementBitKeys.showKeyList(); //FOR TROUBLESHOOTING
}
public void keyTyped(int e) {
// not used - but in case I ever want it
}
还有 BitSet 类:
package com.jayavon.game.helper;
import java.util.BitSet;
public class BitKeys{
private BitSet keyBits = new BitSet(256);
public void keyPressed(final int keyCode) {
keyBits.set(keyCode);
}
public void keyReleased(final int keyCode) {
keyBits.clear(keyCode);
}
public void keyTyped(final int keyCode) {
// don't care
}
public boolean isKeyPressed(final int keyCode) {
return keyBits.get(keyCode);
}
public void showKeyList(){
System.out.println(keyBits.toString());
}
}
我的问题是,当您按住一个移动键时,第一次和第二次“移动”之间的时间比所需的 0.125 毫秒等待时间要长得多。这是一些示例数据:
Set 1:
6059 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - KeyPressed(有效):2.567790275
6620 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - KeyPressed(有效):0.560479937
6670 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - 按键(快速):0.0504469
6710 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - 按键(快速):0.09360516
6750 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - KeyPressed(有效):0.129943376
6791 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - 按键(快速):0.04009505
6821 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - 按键(快速):0.07098997
6851 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - 按键(快速):0.102378686
6902 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - KeyPressed(有效):0.152006677
Set 2:
9690 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - KeyPressed(有效):2.03802468
10272 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - KeyPressed(有效):0.582025645
10322 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - KeyPressed(快速):0.054749323
10342 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - 按键(快速):0.069890042
10372 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - 按键(快速):0.100790212
10412 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - KeyPressed(有效):0.141337411
10462 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - 按键(快速):0.049483458
10462 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - 按键(快速):0.049720381
10512 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - 按键(快速):0.098888524
10542 [AWT-EventQueue-0] 信息 com.jayavon.game.client.MyClient - KeyPressed(有效):0.128729361
现在是提问时间了。显然,第一次移动所花费的时间很长,具体取决于多长时间,所以这是有道理的。我不明白的是为什么第二个“移动”是在 0.5 左右而不是更接近 0.125。从数据中可以看出,按住按键时第三步和第四步的发射速度非常快,以至于它们都小于 0.125。
任何人都可以以任何方式帮助我解决这个问题吗?任何以任何方式改进我的代码的建议确实都会有巨大的帮助。毫秒数。