【问题标题】:Binding Keys to Move an Image绑定键以移动图像
【发布时间】:2015-05-14 02:31:28
【问题描述】:

我正在为一个学校项目开发一款游戏,作为一个步骤,我必须将键绑定到将从 x-y 轴添加/减去的图像。然而,我这样做的方式似乎不起作用,而不是少量添加,x/y 增加了很多,并将图像从屏幕上传送出去。

KeyListener 代码

public void keyPressed(KeyEvent e) {

    if (e.getKeyCode() == 87) {
        up = true ;
        if (e.getKeyCode() == 65) {
            left = true ; 
        }
        if (e.getKeyCode() == 68) {
            right = true ;
        }
        if (e.getKeyCode() == 83) {
            down = true ;
        }
    }

}

@Override
public void keyReleased(KeyEvent e) {

    if (e.getKeyCode() == 87) {
        up = false ;
    }
    if (e.getKeyCode() == 65) {
        left = false; 
    }
    if (e.getKeyCode() == 68) {
        right = false ;
    }
    if (e.getKeyCode() == 83) {
        down = false ;
    }

}

游戏循环

public void run() {

    while(running) {

        //Player movement
        if (up) {
            y++ ;
        }
        if (left) {
            x-- ;
        }
        if (right) {
            x++;
        }
        if (down) {
            y-- ;
        }
        //Player movement

    }
}   

图形循环

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    //Graphical loop start
    g.drawImage(Player, x, y, null) ;       

    //Graphical loop end
    repaint();

【问题讨论】:

  • 这可能与您的更新速度有关。考虑提供一个runnable example 来证明您的问题。这不是代码转储,而是您正在做的事情的一个例子,它突出了您遇到的问题。这将导致更少的混乱和更好的响应
  • 还可以考虑使用键绑定 API 而不是 KeyListener。更多详情请见How to Use Key Bindings
  • 附带说明,您应该在keyPressed 中检查您的牙套。我进行了编辑以更正您的代码格式,并注意到可能存在错误。 (left/right/downup 块内。)
  • e.getKeyCode() == 83 不要使用像83 这样的“幻数”。每个键都有定义的常量,它们(数字)可能会因 JRE 实现或操作系统而异。

标签: java swing keylistener


【解决方案1】:

代码按应有的方式工作。您只忘记了一件事:用于移动图像的while-loop 运行速度比您预期的要快得多。只需插入 Thread.sleep(someDelay) 即可使循环运行得更慢,并且图像应该以更“用户友好”的速度移动。

【讨论】:

    【解决方案2】:

    不回答你的问题,但是:

    if (e.getKeyCode() == 87) 
    

    不要使用“幻数”。人们不知道“87”是什么意思。使用 API 提供的字段名称:

    if (e.getKeyCode() == KeyEvent.VK_UP) 
    

    另外,在您的 paintComponent() 方法中,您有:

    //Graphical loop end
    repaint();
    

    永远不要在绘画方法中调用 repaint()。这将导致无限循环。摆脱那个代码。

    【讨论】:

    • 重绘是为了使图像基于 x 和 y 轴移动和更新。没有它,它不会移动,因为它永远不会更新。
    • @Sumtinlazy 该评论是关于在绘画方法中重新绘画,而不是建议完全避免重新绘画。您应该在状态改变时调用repaint()(或者从具有适当延迟的游戏循环,如果预计屏幕内容几乎每次迭代都会改变)。来自paintComponent()repaint() 如上所述是一个有效的无限循环,并且正在尽可能快地排队绘画。最好在两者之间有一些延迟,因为无论如何屏幕​​都不能任意快速更新。
    • 我是否必须创建一个调用 repaint() 的方法以及如何重绘特定图像。
    • @Sumtinlazy,基本上,当您更改 x/y 的值时,您需要执行 repaint()。因此,您可以在 while (running) 循环中添加 repaint() 方法。当然,正如 Paul 已经提到的,您仍然需要通过添加 Thread.sleep() 来使循环运行得更慢。
    猜你喜欢
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 2013-04-01
    • 2012-02-01
    • 1970-01-01
    相关资源
    最近更新 更多