使用带有箭头键的键绑定
我正在创建一个使用箭头键移动精灵的游戏。我已经添加了箭头键和字母 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
}
I'm creating a game that uses the arrow keys to move a sprite. I've added key bindings for the arrow keys and the letter n, but arrow keys aren't working. Here's my code:
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
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在尝试做 SSCCE 时发现了这一点。当我开始一款新游戏时,我创建了一个新的 Sprite 对象,而没有旧对象的键绑定,因此我的键绑定数据丢失了。我移动了代码以将键绑定添加到 doNewGame() 方法,现在它可以工作了。
I figured it out while trying to do an SSCCE. When I start a new game, I create a new Sprite object without the key bindings of the old one, so my key binding data is lost. I moved my code to add key bindings to the doNewGame() method and it works now.
不要将您的自定义类称为“Panel”。有一个名为“Panel”的 AWT 类,因此您的代码很混乱。使用更具描述性的名称。
默认的 InputMap 用于在组件获得焦点时处理按键绑定。我猜你需要添加:
在你的类的构造函数中。
Don't call your custom class "Panel". There is an AWT class called "Panel" so your code is confusing. Use a more descriptive name.
The default InputMap is used to handle Key Bindings when the component has focus. I would guess you need to add:
in the constructor of your class.