我正在编写一个小游戏。到目前为止,我有一个播放器,可以跟随该播放器在2D打印的瓷砖世界中移动。这里是一个小preview

现在,我的玩家移动代码如下所示:

KeyListener类

public void keyPressed(KeyEvent e) {
    int key = e.getKeyCode();
    for(int i = 0; i < handler.object.size(); i++){
        GameObject tempObject = handler.object.get(i);

        if(tempObject.getId() == ID.Player){
            if(key == KeyEvent.VK_D) tempObject.setVelX(5);
            if(key == KeyEvent.VK_A) tempObject.setVelX(-5);
            if(key == KeyEvent.VK_SPACE && Var.jump == true) {
                tempObject.setVelY(-10);
                Var.jump = false;
            }
        }
    }
public void keyReleased(KeyEvent e) {
    int key = e.getKeyCode();

    for(int i = 0; i < handler.object.size(); i++){
        GameObject tempObject = handler.object.get(i);

        if(tempObject.getId() == ID.Player){
            if(key == KeyEvent.VK_D) tempObject.setVelX(0);
            if(key == KeyEvent.VK_A) tempObject.setVelX(0);
        }
    }


玩家等级

public void tick() {
    if (Var.falling == true) {
        velY += Var.gravity;
        if (velY > 10) {
            velY = 10;
        }
    }
    x += velX;
    y += velY;


这些代码只是类的一部分。

问题

当我用A或D向右或向左移动,然后以某种方式点击另一个键(从a到d /从d到a)时,我的角色停顿了很短的时间,然后在此之后移动短暂的延迟。请参见here

最佳答案

在不知道按键和按键按下的确切顺序的情况下很难说出确切的问题是什么,但是看起来您的程序容易受到重叠的按键/按键按下顺序的影响-例如:

A down -> velocity = -5
D down -> velocity = +5
A up   -> velocity = 0 // but you want it to still be +5


将日志记录添加到游戏代码中以帮助调试这些情况。

有多种方法可以解决此问题,但一种方法是保持当前按下的键的运行计数:

public void keyPressed(KeyEvent e) {
     heldKeys++;
     ... other code ...
}

public void keyReleased(KeyEvent e) {
     heldKeys--;
     ... other code ...
     if(heldKeys == 0) {
          velocity = 0;
     }
}


这很轻巧,但是钝了。一种更完善的方法可能是保留每个密钥状态的记录:

public void keyPressed(KeyEvent e) {
    int key = e.getKeyCode();
    heldKeys.set(key, true);
}


...根据keyStates中的内容进行游戏状态更新。

keyStates可以是HashSet(Integer, Boolean),也可以是您自己的创作中更专业的内容,具体取决于您希望获得多大的效率。



但!有关使用键盘自动重复的讨论,请参见How to know when a user has really released a key in Java?

10-02 04:12