KeyListener 没有按我希望的方式为箭头键工作?
KeyListener not working the way I want it to for arrow keys?
我正在制作贪吃蛇游戏,我已经实现了 KeyListener class,它会在用户按下箭头键或 WASD 键时进行监听。
在snake中,当你按下一个移动键时,如果你只按一次移动键,蛇会继续移动,只有在你输入不同的移动命令后才会向另一个方向移动。但是,在我的程序中,我必须按住键才能让蛇移动,我不能只按一次。我该怎么做才能让我只需要按一下键就可以移动蛇?
此外,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) {
}
您需要将游戏的事件循环变成由 Timer
驱动的东西,它会为您的蛇查询 current_direction
变量。 KeyListener
将设置此 currect_direction
变量。
使用 Timer
可以让您的游戏不受按键重复率的影响。这允许您 increase/decrease 游戏的难度。
我已经解决了我的问题,谢谢@azurefrog、@Hovercraft Full Of Eels 和@AJNeufeld。这是我的解决方案,以防其他人遇到与我相同的问题。免责声明:我还没有完成这个游戏,所以 "snake" 只是一个方块,我仍然需要弄清楚如何让它成为一条真正的蛇。我发布这个只是为了展示我是如何处理蛇的移动的。
首先,我在我的Snake
class(游戏的class)中做了两个全局变量:
private String currentDir = "";
private Timer moveTimer = new Timer(100, new MoveListener());
然后,我做了一个 MoveListener
class 来扩展 ActionListener
class。此 MoveListener
class 作为 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();
}
}
我正在制作贪吃蛇游戏,我已经实现了 KeyListener class,它会在用户按下箭头键或 WASD 键时进行监听。
在snake中,当你按下一个移动键时,如果你只按一次移动键,蛇会继续移动,只有在你输入不同的移动命令后才会向另一个方向移动。但是,在我的程序中,我必须按住键才能让蛇移动,我不能只按一次。我该怎么做才能让我只需要按一下键就可以移动蛇?
此外,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) {
}
您需要将游戏的事件循环变成由 Timer
驱动的东西,它会为您的蛇查询 current_direction
变量。 KeyListener
将设置此 currect_direction
变量。
使用 Timer
可以让您的游戏不受按键重复率的影响。这允许您 increase/decrease 游戏的难度。
我已经解决了我的问题,谢谢@azurefrog、@Hovercraft Full Of Eels 和@AJNeufeld。这是我的解决方案,以防其他人遇到与我相同的问题。免责声明:我还没有完成这个游戏,所以 "snake" 只是一个方块,我仍然需要弄清楚如何让它成为一条真正的蛇。我发布这个只是为了展示我是如何处理蛇的移动的。
首先,我在我的Snake
class(游戏的class)中做了两个全局变量:
private String currentDir = "";
private Timer moveTimer = new Timer(100, new MoveListener());
然后,我做了一个 MoveListener
class 来扩展 ActionListener
class。此 MoveListener
class 作为 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();
}
}