KeyListener没有按照我想要的箭头键的方式工作?

时间:2017-09-05 20:24:23

标签: java keylistener arrow-keys

我正在制作蛇游戏,并且我实现了KeyListener类,该类在用户按下箭头键或WASD键时进行侦听。

在蛇中,当您按下一个移动键时,如果您只按一次移动键,蛇将继续移动,并且只有在您输入不同的移动命令后才会向另一个方向移动。但是,在我的程序中,我必须按住键才能让蛇移动,我不能只按一次。如何制作它以便我只需要按一次键来移动蛇?

此外,WASD键的工作方式与箭头键不同。当我按下WASD键时,蛇只移动一个挡块然后停止,不像箭头键,只要我按住箭头键,蛇就会移动。如何使WASD键的工作方式与我希望箭头键相同?

以下是代码:

public void keyTyped(KeyEvent e) {
}

public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_A) {
        out.println("Left key pressed");
        // handle snake left movement
    } else if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_D) {
        out.println("Right key pressed");
        // handle snake right movement
    } else if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W) {
        out.println("Up key pressed");
        // handle snake up movement
    } else if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_S) {
        out.println("Down key pressed");
        // handle snake down movement
    }
}

public void keyReleased(KeyEvent e) {
}

2 个答案:

答案 0 :(得分:2)

你需要将游戏的事件循环变成由Timer驱动的东西,它会为你的蛇参考current_direction变量。 KeyListener会设置此currect_direction变量。

使用Timer可让您的游戏独立于重复率。这可以让你增加/减少游戏的难度。

答案 1 :(得分:0)

我已经解决了我的问题,谢谢@azurefrog,@ Hovercraft Full Of Eels和@AJNeufeld。这是我的解决方案,以防其他人遇到与我相同的问题。免责声明:我没有完成这个游戏所以“蛇”只是一个块,我仍然要弄清楚如何使它成为一个真正的蛇。我只是张贴这个来展示我是如何处理蛇的运动的。

首先,我在Snake类(游戏类)中创建了两个全局变量:

private String currentDir = "";
private Timer moveTimer = new Timer(100, new MoveListener());

然后,我创建了一个扩展MoveListener类的ActionListener类。此MoveListener类用作moveTimer

的参数
private class MoveListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        out.println("timer action called");
        int snakeX = 0;
        int snakeY = 0;
        for (int row = 0; row < positions.length; row++) {
            for (int col = 0; col < positions[row].length; col++) {
                if (positions[row][col] == 's') {
                    snakeX = row;
                    snakeY = col;
                }
            }
        }
        if (currentDir.equals("left")) {
            positions[snakeX - 1][snakeY] = 's';
            positions[snakeX][snakeY] = '\u0000';
            repaint();
        } else if (currentDir.equals("right")) {
            positions[snakeX + 1][snakeY] = 's';
            positions[snakeX][snakeY] = '\u0000';
            repaint();
        } else if (currentDir.equals("up")) {
            positions[snakeX][snakeY - 1] = 's';
            positions[snakeX][snakeY] = '\u0000';
            repaint();
        } else if (currentDir.equals("down")) {
            positions[snakeX][snakeY + 1] = 's';
            positions[snakeX][snakeY] = '\u0000';
            repaint();
        }
    }
}

最后,我创建了KeyListener,以便它根据相应的移动键设置变量currentDir,并启动MoveTimer线程。

public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_A) {
        out.println("Left key pressed");
        currentDir = "left";
        moveTimer.start();
    } else if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_D) {
        out.println("Right key pressed");
        currentDir = "right";
        moveTimer.start();
    } else if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W) {
        out.println("Up key pressed");
        currentDir = "up";
        moveTimer.start();
    } else if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_S) {
        out.println("Down key pressed");
        currentDir = "down";
        moveTimer.start();
    }
}