我正在创建一个2D游戏,玩家可以在那里射击子弹。我试图找出当玩家按下按键时如何调用拍摄方法。我正在使用Key Bindings,这对我来说是新的。我已阅读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();
}
答案 0 :(得分:0)
Key bindings(和Action)API尝试将“input”的概念与“action”分离。这允许您有多种类型的“输入”,这些“输入”都可以触发相同的操作。
例如,您可能有按钮,键盘敲击,操纵杆或其他外部控制器,所有这些都能够生成“拍摄”输入。而不是必须为每个输入编写“最终”触发某些操作的代码。你可以简单地将它们全部绑定到一个单独的“动作”,它以简洁的方式相互分离(你可以绑定操纵杆输入的方式与按钮或击键相同)。
所以,我们需要的第一件事就是表明“触发器”已被拉动(或释放),可能就像......
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));