【问题标题】:Need help on KeyEvents需要有关 KeyEvent 的帮助
【发布时间】:2014-05-18 20:47:31
【问题描述】:

简单的问题。我正在尝试重新创建游戏 Pong。我在屏幕上得到了我想要的图形,两个桨随 KeyEvents 一起移动。我唯一的问题是,当我释放一个键时,另一个桨也停止(如果两者同时移动)我确切地知道为什么会发生这种情况,但无法弄清楚修复。发生这种情况是因为当调用 keyReleased 方法时,两个桨都设置为速度 0。我如何以不同的方式编码它,我可以使用 keyReleased 方法分别移动/停止两个桨?

代码:

package pong.main;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PongGame extends JPanel implements ActionListener,KeyListener {

private final int WIDTH = 750;
private final int HEIGHT = 750;
private int DELAY = 20;
private int IMAGE_SIZE = 35;

private ImageIcon paddle_one;
private ImageIcon paddle_two;
private ImageIcon pong_logo;
private ImageIcon pong_ball;
private Timer timer = new Timer(DELAY, this);

private int p1_x = 10;
private int p1_y = 325;

private int p2_x = 710;
private int p2_y = 325;

private int p1_moveX;
private int p1_moveY;

private int p2_moveX;
private int p2_moveY;

public PongGame(){

    timer.start();
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);

    paddle_one = new ImageIcon("C:\\Users\\Bryan\\Pictures\\paddle.gif");
    paddle_two = new ImageIcon("C:\\Users\\Bryan\\Pictures\\paddle.gif");
    pong_logo = new ImageIcon("C:\\Users\\Bryan\\Pictures\\pong_logo.gif");
    pong_ball = new ImageIcon("C:\\Users\\Bryan\\Pictures\\pong_ball.gif");

    setPreferredSize(new Dimension(WIDTH, HEIGHT));
    setBackground(Color.black);

}

public void paintComponent(Graphics g){

    super.paintComponent(g);

    paddle_one.paintIcon(this, g, p1_x, p1_y);
    paddle_two.paintIcon(this, g, p2_x, p2_y);
    pong_ball.paintIcon(this, g, 350, 350);
    pong_logo.paintIcon(this, g, 220, -100);

}

public void actionPerformed(ActionEvent e){

    repaint();

    p1_x += p1_moveX;
    p1_y += p1_moveY;

    p2_x += p2_moveX;
    p2_y += p2_moveY;
}

public void paddle_one_up(){
    p1_moveX = 0;
    p1_moveY = -5;
}

public void paddle_one_down(){
    p1_moveX = 0;
    p1_moveY = 5;
}

public void paddle_two_up(){
    p2_moveX = 0;
    p2_moveY = -5;
}

public void paddle_two_down(){
    p2_moveX = 0;
    p2_moveY = 5;
}

public void keyPressed(KeyEvent e){
    int code = e.getKeyCode();

    if(code == KeyEvent.VK_W){
        paddle_one_up();

    }
    if(code == KeyEvent.VK_S){
        paddle_one_down();

    }

    if(code == KeyEvent.VK_UP){
        paddle_two_up();

    }
    if(code == KeyEvent.VK_DOWN){
        paddle_two_down();

    }
}

public void keyReleased(KeyEvent e){

    int code = e.getKeyCode();

    if(code != KeyEvent.VK_W){
        p1_moveX = 0;
        p1_moveY = 0;
    }

    if(code != KeyEvent.VK_S){
        p1_moveX = 0;
        p1_moveY = 0;
    }

    if(code != KeyEvent.VK_UP){
        p2_moveX = 0;
        p2_moveY = 0;
    }
    if(code != KeyEvent.VK_DOWN){
        p2_moveX = 0;
        p2_moveY = 0;
    }
public void keyTyped(KeyEvent e){}

}

【问题讨论】:

  • 尝试使用else if 应该只是顺序的if 语句。它目前正在做的事情是“如果键不是 W,速度 == 0”。 . .然后它检查“如果键不是 S,速度 == 0”。因此,如果您的密钥是 W,它仍然会通过第二次检查。反之亦然。

标签: java swing keypress keyevent keyrelease


【解决方案1】:
  1. 查看 keyPressed 方法和 keyReleased 方法之间的区别。
  2. 在 keyReleased 中做类似的事情——检查 KeyEvent 对象的键码并采取相应措施。这两种方法之间的差异以及您无法解决此问题表明您的 keyPressed 代码是借用的代码。借用代码是可以的,只要你先看懂了。最好借用想法,然后编写自己的代码。
  3. 甚至更好 - 使用 Key Bindings,它比使用 KeyListeners 更安全、更好。

【讨论】:

  • 我再次检查了 keyRelease,但它仍然在做同样的事情。我对 keyevents 还很陌生,所以如果我遗漏了一些简单的东西,请纠正我。
  • @Bfrank:你没有做同样的事情。你使用的是!= 而不是==,这会给你一个完全不同的逻辑。
  • 好的,我将它们更改为 == 但我得到了相同的结果。
【解决方案2】:

使用keyPressed() 方法的条件逻辑结构,您需要在keyReleased() 中进行类似的检查,以确定在设置任一桨的速度之前释放了哪个键。事实上,您可以释放任何键,keyReleased() 会将 p1 和 p2 的值分配为零。

【讨论】: