使用带有箭头键的键绑定

发布于 2024-12-06 03:43:31 字数 3102 浏览 0 评论 0原文

我正在创建一个使用箭头键移动精灵的游戏。我已经添加了箭头键和字母 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

想你的星星会说话 2024-12-13 03:43:31

我在尝试做 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.

旧人 2024-12-13 03:43:31

不要将您的自定义类称为“Panel”。有一个名为“Panel”的 AWT 类,因此您的代码很混乱。使用更具描述性的名称。

默认的 InputMap 用于在组件获得焦点时处理按键绑定。我猜你需要添加:

setFocusable( true );

在你的类的构造函数中。

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:

setFocusable( true );

in the constructor of your class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文