java - 松开按键时游戏延迟

标签 java awt game-physics keylistener 2d-games

我正在制作一个 java 2d 侧滚动器,但我同时遇到多个键的问题。比如右+上。每当你松开向上键时,你就会停止向右移动,同时慢慢回到地面,即使向右仍然被按下。这是我设置的键盘监听器。 dx 是我的水平移动速度,dy 是垂直高度。以下来自角色类

public void keyPressed(KeyEvent e) {
    int key = e.getKeyCode();
    if (key == KeyEvent.VK_LEFT) {
        dx = -5;
        mainCharacterImageFacing = l.getImage();
        }

    if (key == KeyEvent.VK_RIGHT) {
        dx = 5;
        mainCharacterImageFacing = r.getImage();
    } 

    if (key == KeyEvent.VK_UP) {
        dy = 1;
        mainCharacterImageFacing = r.getImage();
    }

}

public void keyReleased(KeyEvent e) {
    int key = e.getKeyCode();
    if (key == KeyEvent.VK_LEFT);
    dx = 0;
    if (key == KeyEvent.VK_RIGHT)
        dx = 0;
    if (key == KeyEvent.VK_UP)
        {dy = 0;
        mainCharacterImageFacing = r.getImage();
        }

这是主游戏窗口中的一些代码,用于处理调用按键/释放方法以及处理跳跃。

private class AL extends KeyAdapter{
    public void keyReleased(KeyEvent e) {
        p.keyReleased(e);
    }

    public void keyPressed(KeyEvent e) {
        p.keyPressed(e);
    }
}

@Override
public void run() 
{
    long beforeTime;
    long timeDiff;
    long sleep;

    beforeTime = System.currentTimeMillis();
    while(done == false)
    {
        cycle();
        timeDiff = System.currentTimeMillis() - beforeTime;
        sleep = 10 - timeDiff;
        if (sleep < 0 )
            sleep = 2;
        try {
            Thread.sleep(sleep);
        } catch (Exception e)
        {}
        beforeTime = System.currentTimeMillis();
    }
    done = false;
    h = false;
    k = false;
}

boolean h = false;
boolean done = false;   
public void cycle() {
    if (h == false)
        v = v - 2; //jump speed falling
    if (v == 350) //max y value of jump.  Lower numbers = higher jumps
        h = true;
    if (h == true && v <= 470) //starting y value
        {
        v = v + 2; //jump speed rising
        if (v == 470)
            done = true;
    }

}

最佳答案

不要直接在 AL 类(class)中处理你的 Action 。相反,使用 boolean 值并将它们相应地设置为 true/false:

private class AL extends KeyAdapter{
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_LEFT) {
            left = true;
        }

        if (key == KeyEvent.VK_RIGHT) {
            right = true
        } 

        if (key == KeyEvent.VK_UP) {
            //...
        }

    }

    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_LEFT)
            left = false
        if (key == KeyEvent.VK_RIGHT)
            right = false
        if (key == KeyEvent.VK_UP)
            //...
        }
    }

这样做的原因是因为在对按键进行操作时会调用 keyPressed 和 keyReleased,但这意味着它不会与主循环同步。

要移动你的 Sprite ,请在循环中调用一个方法,如果你的条件为真,则相应地移动你的 Sprite ,否则不执行任何操作。

编辑:在检查了您的代码之后,我有一些建议。

首先,查找子像素渲染。使用亚像素渲染让 Sprite 的运动看起来更加流畅。

另一件事是要查找可变时间步长(有时称为增量时间步长)。增量时间可用于确保 Action 与玩家的 fps 同步执行。如果一名玩家的帧率为 60 fps,另一名玩家的帧率为 30 fps,则具有 30 fps 的玩家将看到以一半的速度执行操作。然而,使用增量时间步长时, Action 始终以相同的速度执行。 Here's a good article .

第三件事是你的时机。目前您正在使用System.getCurrentTimeMills。这很糟糕,而且不精确。相反,请使用System.nanoTime

我发现的第四件事是你的跳跃算法。更好的方法是包括加速。首先,您需要声明一个加速度常数(0.1 或 0.2 都可以)并计算垂直速度。当垂直速度达到一定值时,你就会掉落。这是一个小片段,但如果您有重力,您可能需要编辑它。首先将 vSpeed 默认设置为 -8。

public void jump() {
    vSpeed += ACCELERATION;
    if(vSpeed < 8)
        dy += vSpeed;
    else
        vSpeed = -8;
        falling = false;
}

我只是凭空写下这个,但基本上,由于向上移动会带走一个数字,所以当它添加负数时你似乎会跳跃,然后当它达到 0 时你会开始下降,当它达到 0 时你会开始下降,当它达到 0 时你会开始下降,当再次达到8。

关于java - 松开按键时游戏延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19385033/

相关文章:

Java Graphics SetColor 给出 NullPointerException

collision - 圆角碰撞行为

java - 覆盖父类的List类型以避免调用方法时进行强制转换

java - 像电子表格一样在 Java 中递增超过 'Z' 的字符

java - 如何在 Hibernate 中将单独的主键添加到联接表

java - 过滤 jtree - 保留符合条件的所有节点和节点的子节点

java - "Could not find a suitable constructor"使用 Jersey 2 从我的资源类中提取接口(interface)时

java - 如何改变背景颜色?

c++ - 使用物理定律模拟轨道

java - 为什么我的坐标系没有反射(reflect)我请求的标准坐标轴?(LibGdx)