问题
I am trying to create a game so that the player can move in all directions (N,NW,W,SW,S,SE,E,NE) although when I capture the key strokes it will move me once in one of the diagonal directions then, but if I hold them down it switches to one of the cardinal directions(N,W,S,E).
Main Class Key Listener
private class MultiKeyPressListener extends KeyAdapter {
private final Set<Character> pressed = new HashSet<Character>();
@Override
public synchronized void keyPressed(KeyEvent e) {
pressed.add(e.getKeyChar());
if(pressed.size() > 1){
System.out.println(pressed);
//LEFT UP PRESSED
if (e.getKeyCode() == KeyEvent.VK_LEFT && e.getKeyCode() == KeyEvent.VK_UP
|| e.getKeyCode() == KeyEvent.VK_A && e.getKeyCode() == KeyEvent.VK_W) {
player.direction = "NW";
}
//UP RIGHT PRESSED
if (e.getKeyCode() == KeyEvent.VK_UP && e.getKeyCode() == KeyEvent.VK_RIGHT
|| e.getKeyCode() == KeyEvent.VK_W && e.getKeyCode() == KeyEvent.VK_D) {
player.direction = "NE";
}
//RIGHT DOWN PRESSED
if (e.getKeyCode() == KeyEvent.VK_RIGHT && e.getKeyCode() == KeyEvent.VK_DOWN
|| e.getKeyCode() == KeyEvent.VK_S && e.getKeyCode() == KeyEvent.VK_D) {
player.direction = "SE";
}
}else{
//DOWN LEFT PRESSED
if (e.getKeyCode() == KeyEvent.VK_LEFT && e.getKeyCode() == KeyEvent.VK_DOWN
|| e.getKeyCode() == KeyEvent.VK_S && e.getKeyCode() == KeyEvent.VK_A) {
player.direction = "SW";
}
//LEFT PRESSED
if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_A) {
player.direction = "W";
}
//DOWN PRESSED
if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_S) {
player.direction = "S";
}
//RIGHT PRESSED
if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_D) {
player.direction = "E";
}
//UP PRESSED
if (e.getKeyCode() == KeyEvent.VK_W || e.getKeyCode() == KeyEvent.VK_UP) {
player.direction = "N";
}
}
player.move();
}
@Override
public synchronized void keyReleased(KeyEvent e) {
pressed.remove(e.getKeyChar());
}
}
Player Class
public void move(){
if(direction.equals("N")){
y-= moveRate;
}else if(direction.equals("NW")){
y-= moveRate;
x-= moveRate;
}else if(direction.equals("W")){
x-= moveRate;
}else if(direction.equals("SW")){
x-= moveRate;
y+= moveRate;
}else if(direction.equals("S")){
y+= moveRate;
}else if(direction.equals("SE")){
y+= moveRate;
x+= moveRate;
}else if(direction.equals("E")){
x+= moveRate;
}else if(direction.equals("NE")){
x+= moveRate;
y-= moveRate;
}
//System.out.println("Moving " + direction);
}
回答1:
You're not going to receive two events simultaneously, that is you won't receive KeyEvent.VK_LEFT AND KeyEvent.VK_UP, you'll only receive one after the other.
What you should try and do, is each time a key is pressed, raise a flag or add it to some kind of List, when a key is released, reset the flag or remove it from the List.
When you want to determine which direction the character is moving, you would inspect each of these flags and make your decision about the movement...
I would also recommend the use of Key Bindings over KeyListener, as it does not suffer from the same focus related issues...
For example
- Problems with Java's Paint method, ridiculous refresh velocity (this is quite interesting, as it I'll accelerate the object while the key is pressed (to a maximum speed) and will decelerate the object after you release it, but that's just me)
- How can i make multiple Key Bindings work at the same time?
- Detecting multiple keypresses in java
来源:https://stackoverflow.com/questions/20202477/moving-player-in-semi-cardinal-directions-using-java-canvas