Reputation: 5
In my school, as a assignment, I have to make improved version of "SNAKE" game.
(I will not add further description since this is very famous)
I have trouble dealing with keyboard inputs.
Things below are summary of my code.
CODE
Initiation part
private final int DELAY = 500; //500ms every event
timer = new Timer(DELAY, this);
timer.start();
Keyboard input part (PROBLEM)
int key=e.getKeyCode();
if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
leftDirection = true;
upDirection = false;
downDirection = false;
}
if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
rightDirection = true;
upDirection = false;
downDirection = false;
}
if ((key == KeyEvent.VK_UP) && (!downDirection)) {
upDirection = true;
rightDirection = false;
leftDirection = false;
}
if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
downDirection = true;
rightDirection = false;
leftDirection = false;
}
My program does not handle multiple quick inputs properly.
For example, lets say snake was moving to right.
ooooooO (->)
If I press "up" and "left" quickly during the DELAY (which is 500 ms),
then the snake heads left and moves upon its body.
oooooOo (<-)
How should I change Keyboard input part to solve this problem?
CONDITION
Professor gave template code for the Keyboard input parts like this.
private class TAdapter extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
//Keyboard input part (PROBLEM)
Upvotes: 0
Views: 183
Reputation: 44414
You’ll need two sets of fields. One set describes the directional key most recently pressed, while the other describes the actual direction of movement most recently implemented in the Timer action:
private boolean leftPressed;
private boolean rightPressed;
private boolean upPressed;
private boolean downPressed;
private boolean movingLeft;
private boolean movingRight;
private boolean movingUp;
private boolean movingDown;
As you would expect, the “Pressed” fields are only set by a KeyListener.
The Timer action should then read those *Pressed fields, and set the moving* fields accordingly. This allows your KeyListener to forbid reversal of direction based on the last implemented direction, rather than just the last pressed key:
if (key == KeyEvent.LEFT && !movingRight) {
leftPressed = true;
rightPressed = false;
upPressed = false;
downPressed = false;
}
You may find that using an enum is easier than maintaining a group of four booleans. For instance:
private enum Direction { LEFT, RIGHT, UP, DOWN }
private Direction lastKeyPressed;
private Direction movement;
Upvotes: 1