Java 学习关键事件

Java 学习关键事件,java,swing,Java,Swing,我对java还比较陌生,我试图学习如何在有这个圆圈的地方制作一个程序,我可以使用箭头键来移动它。通过一系列的例子,我能够把一些东西组合起来。尽管我不确定如何创建KeyEvent。我所缺少的任何帮助都将是非常棒的 这就是我目前所拥有的 import javax.swing.WindowConstants; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import

我对java还比较陌生,我试图学习如何在有这个圆圈的地方制作一个程序,我可以使用箭头键来移动它。通过一系列的例子,我能够把一些东西组合起来。尽管我不确定如何创建KeyEvent。我所缺少的任何帮助都将是非常棒的

这就是我目前所拥有的

    import javax.swing.WindowConstants;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.event.KeyEvent;

@SuppressWarnings("serial")
public class Game extends JPanel 
{

    int x = 0;
    int y = 0;
    private void moveBallUP() {
        x = x + 0;
        y = y + 1;       
    }

    private void moveBallDOWN() {
        x = x + 0;
        y = y - 1;       
    }

    private void moveBallLEFT() {
        x = x + 1;
        y = y + 0;       
    }

    private void moveBallRIGHT() {
        x = x - 1;
        y = y + 0;       
    }

    @Override
    public void paint(Graphics g) 
    {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);     
            g.setColor(Color.red);
        g2d.fillOval(y, x, 50, 50);
    }

    public static void main(String[] args) throws InterruptedException 
    {
        JFrame frame = new JFrame("Sample Frame");
        Game game = new Game();
        frame.add(game);
        frame.setSize(300, 400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        if (event.getKeyCode() == KeyEvent.VK_UP) 
        {
            game.moveBallUP();
            game.repaint();
            Thread.sleep(10);
        }

        if (event.getKeyCode() == KeyEvent.VK_DOWN) 
        {
            game.moveBallDOWN();
            game.repaint();
            Thread.sleep(10);
        }

        if (event.getKeyCode() == KeyEvent.VK_LEFT) 
        {
            game.moveBallLEFT();
            game.repaint();
            Thread.sleep(10);
        }

        if (event.getKeyCode() == KeyEvent.VK_RIGHT) 
        {
            game.moveBallRIGHT();
            game.repaint();
            Thread.sleep(10);
        }
    }
}

解决这个问题有几个步骤:首先,使用
keylister
。将以下代码添加到
游戏
类中;这将表示按下了哪些按钮:

private boolean upPressed=false;
private boolean downPressed=false;
private boolean leftPressed=false;
private boolean rightPressed=false;
然后,将其添加到
main
方法中:

frame.addKeyListener(new KeyListener() {
    @Override
    public void keyReleased(KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.VK_UP:
                game.upPressed=false;
                break;
            case KeyEvent.VK_DOWN:
                game.downPressed=false;
                break;
            case KeyEvent.VK_LEFT:
                game.leftPressed=false;
                break;
            case KeyEvent.VK_RIGHT:
                game.rightPressed=false;
                break;

        }
    }

    @Override
    public void keyTyped(KeyEvent event) {

    }

    @Override
    public void keyPressed(KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.VK_UP:
                game.upPressed=true;
                break;
            case KeyEvent.VK_DOWN:
                game.downPressed=true;
                break;
            case KeyEvent.VK_LEFT:
                game.leftPressed=true;
                break;
            case KeyEvent.VK_RIGHT:
                game.rightPressed=true;
                break;

        }
    }
});
Timer timer = new Timer(10,(e)->{
    if (game.upPressed)
    {
        game.moveBallUP();
        game.repaint();
    }

    if (game.downPressed)
    {
        game.moveBallDOWN();
        game.repaint();
    }

    if (game.leftPressed)
    {
        game.moveBallLEFT();
        game.repaint();
    }

    if (game.rightPressed)
    {
        game.moveBallRIGHT();
        game.repaint();
    }
});
timer.start();
基本上,当按下按钮时,将我们创建的变量设置为true,当释放按钮时,将设置为false。最后,在
main
方法中添加一个
Timer

frame.addKeyListener(new KeyListener() {
    @Override
    public void keyReleased(KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.VK_UP:
                game.upPressed=false;
                break;
            case KeyEvent.VK_DOWN:
                game.downPressed=false;
                break;
            case KeyEvent.VK_LEFT:
                game.leftPressed=false;
                break;
            case KeyEvent.VK_RIGHT:
                game.rightPressed=false;
                break;

        }
    }

    @Override
    public void keyTyped(KeyEvent event) {

    }

    @Override
    public void keyPressed(KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.VK_UP:
                game.upPressed=true;
                break;
            case KeyEvent.VK_DOWN:
                game.downPressed=true;
                break;
            case KeyEvent.VK_LEFT:
                game.leftPressed=true;
                break;
            case KeyEvent.VK_RIGHT:
                game.rightPressed=true;
                break;

        }
    }
});
Timer timer = new Timer(10,(e)->{
    if (game.upPressed)
    {
        game.moveBallUP();
        game.repaint();
    }

    if (game.downPressed)
    {
        game.moveBallDOWN();
        game.repaint();
    }

    if (game.leftPressed)
    {
        game.moveBallLEFT();
        game.repaint();
    }

    if (game.rightPressed)
    {
        game.moveBallRIGHT();
        game.repaint();
    }
});
timer.start();
这将每10毫秒触发一次,并在按下按钮时调用移动方法

我已经测试过了,并且知道它是有效的,但是你的移动方法将圆移动到了错误的方向。我想你能解决这个问题

编辑:错误在这一行:

g2d.fillOval(y, x, 50, 50);
将其更改为:

g2d.fillOval(x,y , 50, 50);

解决这个问题有几个步骤:首先,使用
keylister
。将以下代码添加到
游戏
类中;这将表示按下了哪些按钮:

private boolean upPressed=false;
private boolean downPressed=false;
private boolean leftPressed=false;
private boolean rightPressed=false;
然后,将其添加到
main
方法中:

frame.addKeyListener(new KeyListener() {
    @Override
    public void keyReleased(KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.VK_UP:
                game.upPressed=false;
                break;
            case KeyEvent.VK_DOWN:
                game.downPressed=false;
                break;
            case KeyEvent.VK_LEFT:
                game.leftPressed=false;
                break;
            case KeyEvent.VK_RIGHT:
                game.rightPressed=false;
                break;

        }
    }

    @Override
    public void keyTyped(KeyEvent event) {

    }

    @Override
    public void keyPressed(KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.VK_UP:
                game.upPressed=true;
                break;
            case KeyEvent.VK_DOWN:
                game.downPressed=true;
                break;
            case KeyEvent.VK_LEFT:
                game.leftPressed=true;
                break;
            case KeyEvent.VK_RIGHT:
                game.rightPressed=true;
                break;

        }
    }
});
Timer timer = new Timer(10,(e)->{
    if (game.upPressed)
    {
        game.moveBallUP();
        game.repaint();
    }

    if (game.downPressed)
    {
        game.moveBallDOWN();
        game.repaint();
    }

    if (game.leftPressed)
    {
        game.moveBallLEFT();
        game.repaint();
    }

    if (game.rightPressed)
    {
        game.moveBallRIGHT();
        game.repaint();
    }
});
timer.start();
基本上,当按下按钮时,将我们创建的变量设置为true,当释放按钮时,将设置为false。最后,在
main
方法中添加一个
Timer

frame.addKeyListener(new KeyListener() {
    @Override
    public void keyReleased(KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.VK_UP:
                game.upPressed=false;
                break;
            case KeyEvent.VK_DOWN:
                game.downPressed=false;
                break;
            case KeyEvent.VK_LEFT:
                game.leftPressed=false;
                break;
            case KeyEvent.VK_RIGHT:
                game.rightPressed=false;
                break;

        }
    }

    @Override
    public void keyTyped(KeyEvent event) {

    }

    @Override
    public void keyPressed(KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.VK_UP:
                game.upPressed=true;
                break;
            case KeyEvent.VK_DOWN:
                game.downPressed=true;
                break;
            case KeyEvent.VK_LEFT:
                game.leftPressed=true;
                break;
            case KeyEvent.VK_RIGHT:
                game.rightPressed=true;
                break;

        }
    }
});
Timer timer = new Timer(10,(e)->{
    if (game.upPressed)
    {
        game.moveBallUP();
        game.repaint();
    }

    if (game.downPressed)
    {
        game.moveBallDOWN();
        game.repaint();
    }

    if (game.leftPressed)
    {
        game.moveBallLEFT();
        game.repaint();
    }

    if (game.rightPressed)
    {
        game.moveBallRIGHT();
        game.repaint();
    }
});
timer.start();
这将每10毫秒触发一次,并在按下按钮时调用移动方法

我已经测试过了,并且知道它是有效的,但是你的移动方法将圆移动到了错误的方向。我想你能解决这个问题

编辑:错误在这一行:

g2d.fillOval(y, x, 50, 50);
将其更改为:

g2d.fillOval(x,y , 50, 50);

“我对java比较陌生”-欢迎,使用注册特定关键事件的通知作为一般建议,您应该覆盖
paintComponent
,而不是
paint
。您还可以在“事件驱动”环境中操作,该环境使用观察者模式在事件发生时提供通知。使用Swing时,还应避免使用ad.sleep,因为这样可以防止UI被更新或无法响应新事件“我对java比较陌生”-欢迎使用注册特定关键事件的通知作为一般建议,您应该覆盖
paintComponent
,而不是
paint
。您还可以在“事件驱动”环境中操作,该环境使用观察者模式在事件发生时提供通知。使用Swing时,您还应避免使用
Thead.sleep
,因为您可能会阻止用户界面被更新或无法对新事件做出响应。由于回复太晚,这对您帮助很大。对于回复太晚,我深表歉意,但非常感谢。