我正在创建一个使用箭头键移动精灵的游戏。我已经为箭头键和字母n添加了键绑定,但箭头键不起作用。这是我的代码:
public class MyPanel extends JPanel {
Sprite sprite = new Sprite();
Timer gameClock = new Timer(DELAY, new ActionListener(){
public void actionPerformed(ActionEvent e){
sprite.move();
// omit other methods
}
});
// omit other member variables
public MyPanel(){
Abstract Action newGameAction = new AbstractAction("new game") {
public void actionPerformed(ActionEvent e){
doNewGame();
}
}
setFocusable(true);
addKeyBinding(new Pair<String, Action>("N", newGameAction));
ArrayList<Pair<String, Action>> pairs = sprite.findKeyBindingPairs();
for (Pair<String, Action> p : pairs)
addKeyBindings(p);
gameClock.start();
// omit other panel init
}
private void addKeyBindings(Pair<String, Action> pair) {
String key = pair.getFirstElement();
Action action = pair.getSecondElement();
String desc = action.getValue(AbstractAction.NAME).toString();
getInputMap().put(KeyStroke.getKeyStroke(key), desc);
getActionMap().put(desc, action);
}
// omit other methods
}
public class Sprite {
private class ChangeDirAction extends AbstractAction {
int dx, dy;
ChangeDirAction(String name, int dx, int dy){
super(name);
this.dx = dx;
this.dy = dy;
}
public void actionPerformed(ActionEvent e){
setVelocity(dx, dy);
}
}
private int dx_, dy_;
Point pos;
// omit other instance variables
public void move(){
// With printlns dx_ and dy_ are both 0 here. Why?
Point newPos = new Point(pos);
newPos.translate(dx_, dy_);
// omit code to test whether newPos is valid
if (isWall(newPos) || isOutsidePanel(newPos))
setVelocity(0, 0);
else
pos = newPos;
}
private void setVelocity(int dx, int dy){
dx_ = dx;
dy_ = dy;
// With printlns dx_ and dy_ change when arrow keys are pressed
}
public ArrayList<Pair<String, Action>> findKeyBindingPairs(){
Pair<String, Action> leftPair = new Pair<String, Action>("LEFT", new ChangeDirAction("left", -1, 0));
Pair<String, Action> rightPair = new Pair<String, Action>("RIGHT", new ChangeDirAction("right", 1, 0));
Pair<String, Action> upPair = new Pair<String, Action>("UP", new ChangeDirAction("up", 0, -1));
Pair<String, Action> downPair = new Pair<String, Action>("DOWN", new ChangeDirAction("down", 0, 1));
ArrayList<Pair<String, Action>> result = new ArrayList<Pair<String, Action>>();
result.add(leftPair);
result.add(rightPair);
result.add(upPair);
result.add(downPair);
return result;
}
// omit other methods
}
答案 0 :(得分:4)
我在尝试做SSCCE时想通了。当我开始一个新游戏时,我创建了一个新的Sprite对象而没有旧游戏的键绑定,所以我的键绑定数据丢失了。我移动了我的代码,为doNewGame()方法添加了键绑定,现在可以正常工作。
答案 1 :(得分:2)
不要将您的自定义类称为“面板”。有一个名为“Panel”的AWT类,所以你的代码很混乱。使用更具描述性的名称。
默认的InputMap用于在组件具有焦点时处理键绑定。我猜你需要补充一下:
setFocusable( true );
在你班级的构造函数中。