I am making a the snake game and I have implemented the KeyListener class that listens to when the user presses the arrow keys or WASD keys.
In snake, when you press a movement key, the snake will continue to move if you just press a movement key once, and will only go in another direction once you enter a different movement command. However, in my program I have to hold the key down for the snake to move, I can't just press it once. How do I make it so that I just have to press the key once to move the snake?
Also, the WASD keys are working differently than the arrow keys. When I press a WASD key, the snake only moves one block and then stops, unlike the arrow keys where the snake moves as long as I hold down the arrow keys. How do I make the WASD keys work the same way as I want the arrow keys to work?
Here is the code:
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) {
}
I have solved my problem, thank you @azurefrog, @Hovercraft Full Of Eels, and @AJNeufeld. Here is my solution in case other people have the same problem as mine. Disclaimer: I am not done with this game so the "snake" is just a block, I still have to figure out how to make it an actual snake. I am just posting this to show how I handled the movement of the snake.
First, I made two global variables in my Snake
class (the class of the game):
private String currentDir = "";
private Timer moveTimer = new Timer(100, new MoveListener());
Then, I made a MoveListener
class that extends the ActionListener
class. This MoveListener
class serves as the parameter for the 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();
}
}
}
Finally, I made my KeyListener
so that it simply set the variable currentDir
based on the corresponding movement keys, and started the MoveTimer
thread.
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();
}
}