2011-09-22 62 views
4

我正在创建一个使用箭头键移动精灵的游戏。我为箭头键和字母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 

} 
+1

我在试图做SSCCE时想通了。当我开始一个新的游戏时,我创建了一个新的Sprite对象,而没有旧的键绑定,所以我的键绑定数据丢失了。我将我的代码移到了doNewGame()方法的键绑定中,并且它现在可以工作。 – Eva

+2

这是SSCCE如此高度推荐的原因之一:-)顺便说一句,你可以自己添加一个答案,并接受它。 – kleopatra

回答

4

我在试图做SSCCE时想通了。当我开始一个新的游戏时,我创建了一个新的Sprite对象,而没有旧的键绑定,所以我的键绑定数据丢失了。我将我的代码移到了doNewGame()方法的键绑定中,并且它现在可以工作。

2

不要调用您的自定义类“面板”。有一个名为“Panel”的AWT类,所以你的代码很混乱。使用更具描述性的名称。

当组件具有焦点时,默认的InputMap用于处理键绑定。我想你需要补充:

setFocusable(true); 

在你的类的构造函数。

+0

setFocusable()在我的构造函数中。箭头键仍然不起作用,而字母n工作正常。 – Eva

+1

您发布的代码没有显示或显示如何创建“N”绑定。发布证明问题的SSCCE。 – camickr