可以在实现 KeyListener 接口的类中监听键盘事件,根据用户按下的键来移动人物或者推箱子。
首先,在 map 类中添加 KeyListener:
public class map extends JPanel implements box1, KeyListener {
public map() {
addKeyListener(this);
setFocusable(true);
}
//...
}
接着,实现 KeyListener 的方法:
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch (key) {
case KeyEvent.VK_UP:
move(-1, 0); // 向上移动
break;
case KeyEvent.VK_DOWN:
move(1, 0); // 向下移动
break;
case KeyEvent.VK_LEFT:
move(0, -1); // 向左移动
break;
case KeyEvent.VK_RIGHT:
move(0, 1); // 向右移动
break;
}
}
private void move(int dx, int dy) {
int newX = x + dx; // 计算新位置
int newY = y + dy;
if (newX < 0 || newY < 0 || newX >= box.length || newY >= box[0].length) { // 判断是否越界
return;
}
if (box[newX][newY] == 4 || box[newX][newY] == 1) { // 判断新位置是否是墙或空地
return;
}
if (box[newX][newY] == 2) { // 如果新位置是箱子,需要判断是否能够推动箱子到新位置
int nextBoxX = newX + dx;
int nextBoxY = newY + dy;
if (nextBoxX < 0 || nextBoxY < 0 || nextBoxX >= box.length || nextBoxY >= box[0].length) { // 判断箱子是否越界
return;
}
if (box[nextBoxX][nextBoxY] == 4 || box[nextBoxX][nextBoxY] == 2) { // 判断箱子下一个位置是否是墙或箱子
return;
}
box[newX][newY] = 3; // 将原来的箱子变成目标点
box[nextBoxX][nextBoxY] = 2; // 将新位置设置为箱子
}
x = newX; // 更新人物位置
y = newY;
repaint(); // 重新绘制地图
}
@Override
public void keyReleased(KeyEvent e) {}
@Override
public void keyTyped(KeyEvent e) {}
在 move 方法中,首先判断新位置是否合法(不能越界、不能是墙或空地),如果是合法的,则根据新位置更新人物的位置。如果新位置上有箱子,还需要进一步判断能否推动箱子到下一个位置。如果能够推动,就将原来的箱子变成目标点,将新位置设置为箱子,并更新人物的位置。
最后,在 main 方法中创建 map 对象,并添加到 JFrame 中:
public static void main(String[] args) {
JFrame frame = new JFrame("推箱子");
map gameMap = new map();
frame.getContentPane().add(gameMap);
frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
运行程序,使用方向键来移动人物和推箱子。




