使用键绑定调用方法



我正在创建一个2D游戏,玩家可以在其中射击子弹。我正在尝试弄清楚当玩家按下键时如何调用射击方法。我正在使用键绑定,这对我来说是新的。我已经阅读了 API,但仍然无法让它工作。建议会有所帮助

这是我的键盘输入代码:

public PlayerTwo (){
playertwo = Toolkit.getDefaultToolkit().createImage("cal.png");
bullets = new ArrayList();
tm.start();
InputMap im = getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up.released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down.released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left.released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right.released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "space.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), "space.released");

am.put("up.pressed", new MoveAction(-1, 0));
am.put("up.released", new MoveAction(0, 0));
am.put("down.pressed", new MoveAction(1, 0));
am.put("down.released", new MoveAction(0, 0));
am.put("left.pressed", new MoveAction(0, -1));
am.put("left.released", new MoveAction(0, 0));
am.put("right.pressed", new MoveAction(0, 1));
am.put("right.released", new MoveAction(0, 0));
//Shoot.getActionMap();
}

键绑定(和操作(API 尝试将"输入"的概念与"操作"分离。 这允许您拥有多种类型的"输入",这些"输入"都可以触发相同的操作。

例如,您可能有按钮、键盘笔划、操纵杆或其他外部控制器,所有这些都能够生成"拍摄"输入。而不是必须为每个"最终"触发某些操作的输入编写代码。 您可以简单地以简洁的方式将它们全部绑定到一个相互分离的"动作"上(您可能绑定操纵杆输入的方式与按钮或击键的方式不同(。

所以,我们需要做的第一件事是以某种方式指示"触发器"已被拉动(或释放(,也许是这样的......

public class ShootAction extends AbstractAction {
private boolean isShooting;
public ShootAction(boolean isShooting) {
this.isShooting = isShooting;
}
@Override
public void actionPerformed(ActionEvent e) {
}
}

好吧,好吧,这有点无聊,实际上并没有"做"任何事情。 我们需要的是某种"状态经理",我们可以告诉他触发器已被按下或释放。 重要的是要注意,决定"什么"或"如何"拍摄不是ShootAction的责任,它应该纯粹专注于通知"模型"或"控制器"状态已经改变,以便它可以以某种有意义的方式做出反应。

因此,假设我们有一些控制器可以提供拍摄状态管理......

public class SomeAwesomeGameController ... {
public void setShooting(boolean shooting) {...}
public boolean isShooting() {...}
}

我们可以将它的一个实例传递给操作并使用它来更新状态......

public class ShootAction extends AbstractAction {
private boolean isShooting;
private SomeAwesomeGameController controller;
public ShootAction(SomeAwesomeGameController controller, boolean isShooting) {
this.controller = controller;
this.isShooting = isShooting;
}
@Override
public void actionPerformed(ActionEvent e) {
controller.setShooting(isShooting);
}
}

这样做的原因之一(除了解耦代码(是因为第一次击键和重复击键之间存在操作系统延迟。通过消除依赖实际重复事件的需要(只关心状态何时更改(,我们消除了这种延迟。

最后,我们可以将它们全部绑定在一起:P

public class PlayerTwo ... {
// Don't forget to assign this value ;)
private SomeAwesomeGameController controller;
public PlayerTwo() {
InputMap im = getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "space.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), "space.released");
am.put("space.pressed", new ShootAction(controller, true));
am.put("space.released", new ShootAction(controller, false));

最新更新