keyPressed 事件第一次重复时缓慢

2024-04-30

好吧,我很抱歉这是一个非常奇怪的问题,但这让我发疯。

我通过以下方式处理游戏的 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。

任何人都可以以任何方式帮助我解决这个问题吗?任何以任何方式改进我的代码的建议确实都会有巨大的帮助。毫秒数。


在 @aioobe 的巨大帮助下,我解决了这个问题。

Timer timer = new Timer();
timer.schedule(new TimerTask() {
    public void run() {
        checkKeyStrokes();
    }
}, 0, 0135);

public void checkKeyStrokes(){
    if (movementBitKeys.isKeyPressed(87)){ //w
        keyPressed(87);
    }
    if (movementBitKeys.isKeyPressed(65)){ //a
        keyPressed(65);
    }
    if (movementBitKeys.isKeyPressed(83)){ //s
        keyPressed(83);
    }
    if (movementBitKeys.isKeyPressed(68)){ //d
        keyPressed(68);
    }
}

希望这对其他人有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

keyPressed 事件第一次重复时缓慢 的相关文章

随机推荐