KeyListener 无法按照我希望的方向键方式工作?

问题描述 投票:0回答:3

我正在制作一个贪吃蛇游戏,并且我已经实现了 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) {
}
java keylistener arrow-keys
3个回答
2
投票

您需要将游戏的事件循环变成由

Timer
驱动的东西,它会为您的蛇查询
current_direction
变量。
KeyListener
将设置此
currect_direction
变量。

使用

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


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();
    }
}

0
投票

我用的就是这个。只需使用按下和释放功能即可。

package main;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyHandler implements KeyListener {

    public boolean upPressed, downPressed, leftPressed, rightPressed, shotPressed;

    GamePanel gp;
    

    public KeyHandler(GamePanel gp) {
        super();
        this.gp = gp;
    }
    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        
        int code = e.getKeyCode();
         
        if(code == KeyEvent.VK_W || code == KeyEvent.VK_UP) {
            upPressed = true;
        }
        if(code == KeyEvent.VK_S || code == KeyEvent.VK_DOWN) {
            downPressed = true;
        }   
        if(code == KeyEvent.VK_A || code == KeyEvent.VK_LEFT) {
            leftPressed = true;
        }   
        if(code == KeyEvent.VK_D || code == KeyEvent.VK_RIGHT) {
            rightPressed = true;
        }
        if(code == KeyEvent.VK_SPACE) {
            shotPressed = true;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        
        int code = e.getKeyCode();
         
        if(code == KeyEvent.VK_W || code == KeyEvent.VK_UP) {
            upPressed = false;
        }
        if(code == KeyEvent.VK_S || code == KeyEvent.VK_DOWN) {
            downPressed = false;
        }   
        if(code == KeyEvent.VK_A || code == KeyEvent.VK_LEFT) {
            leftPressed = false;
        }   
        if(code == KeyEvent.VK_D || code == KeyEvent.VK_RIGHT) {
            rightPressed = false;
        }
        if(code == KeyEvent.VK_F3) {
            this.gp.debug = !this.gp.debug;
            System.out.println(this.gp.debug ? "Debug Mode On" : "Debug Mode Off");
        }
        if(code == KeyEvent.VK_SPACE) {
            shotPressed = false;
        }
    

    }

}

但是如果是蛇一样的运动,我不知道

© www.soinside.com 2019 - 2024. All rights reserved.