如何在Player子类中调用主类GameManager的KeyEvents实现玩家移动
解决Player子类中按键控制移动/停止的问题
我来帮你搞定这个按键控制的难题!你当前的核心困境是:Player类没法直接获取GameManager里的实时按键状态——KeyEvent只是按键触发时的临时事件对象,不能用来持续检测按键是否处于按下状态。我们可以通过维护按键状态变量+让Player持有GameManager引用的方式解决,具体步骤如下:
步骤1:在GameManager中添加按键状态变量
首先在GameManager类的成员变量区域,添加布尔变量记录按键的按下/松开状态:
// GameManager类的成员变量区 private boolean leftPressed = false; private boolean rightPressed = false; // 如果需要上下移动,可额外添加upPressed、downPressed
步骤2:在KeyListener方法中更新状态
修改GameManager里的keyPressed和keyReleased方法,根据事件更新上面的布尔变量:
@Override public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_LEFT) { leftPressed = true; } else if (keyCode == KeyEvent.VK_RIGHT) { rightPressed = true; } // 如需上下控制,在这里添加VK_UP/VK_DOWN的判断 } @Override public void keyReleased(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_LEFT) { leftPressed = false; } else if (keyCode == KeyEvent.VK_RIGHT) { rightPressed = false; } // 上下控制同理 } // 必须实现的keyTyped方法(空实现即可,我们不需要处理字符输入) @Override public void keyTyped(KeyEvent e) { // 无需任何操作 }
步骤3:让Player持有GameManager的引用
你的Enemy类已经通过构造方法接收了GameManager的引用,我们给Player也做同样的处理:
先修改Player类的构造和成员变量
public class Player { private GameManager gameManager; // 添加GameManager引用 private int x, y; private int velX = 0; // 初始速度设为0,默认不移动 // 你的其他成员变量(比如图片、velY等) // 修改构造方法,接收GameManager引用 public Player(GameManager gameManager, int initialX, int initialY) { this.gameManager = gameManager; this.x = initialX; this.y = initialY; } // 你的其他方法... }
然后修改GameManager中创建Player的代码
把原来的Player实例化代码改成:
// GameManager类中创建Player的部分 this.player = new Player( this, this.canvasWidth - (Math.abs(rng.nextInt()) % (this.canvasWidth / 2)), (Math.abs(rng.nextInt()) % this.canvasHeight) );
步骤4:给GameManager添加按键状态的Getter方法
为了让Player能安全访问按键状态,在GameManager中添加Getter:
// GameManager类中添加 public boolean isLeftPressed() { return leftPressed; } public boolean isRightPressed() { return rightPressed; } // 如果有上下控制,添加对应的isUpPressed()、isDownPressed() // 另外可以添加获取画布宽度的方法,用于边界检测 public int getCanvasWidth() { return canvasWidth; }
步骤5:在Player的performAction中实现移动逻辑
现在就可以在Player的performAction方法里,根据按键状态设置速度,实现按下移动、松开停止:
public void performAction() { // 根据按键状态设置水平速度 if (gameManager.isLeftPressed()) { velX = -6; // 向左移动的速度,数值可根据游戏节奏调整 } else if (gameManager.isRightPressed()) { velX = 6; // 向右移动的速度 } else { velX = 0; // 无按键按下时,速度归0,停止移动 } // 更新玩家位置 x += velX; // 可选:添加边界检测,防止玩家移出屏幕 int playerWidth = getCurrentImage().getWidth(); // 假设你有获取玩家图片的方法 if (x < 0) { x = 0; } else if (x > gameManager.getCanvasWidth() - playerWidth) { x = gameManager.getCanvasWidth() - playerWidth; } }
为什么原来的方法行不通?
KeyEvent是一次性事件对象,只有在按键按下/松开的瞬间才会被创建,没法在Player的performAction循环中持续获取按键状态。我们需要用布尔变量来持续记录按键的状态,这样每一帧更新时都能检查当前的按键情况。
内容的提问来源于stack exchange,提问作者Huseyin Yesiler
相关产品推荐
相关产品推荐

