【问题标题】:Java Key Bindings and Arrow KeysJava 键绑定和箭头键
【发布时间】:2014-12-29 16:31:05
【问题描述】:

我正在编写一个小型自上而下的游戏,玩家在二维数组中移动,由箭头键控制。
我一定看过所有关于键绑定的教程,但我无法让我的键绑定更新主“地板”对象。帮助!对不起,文字墙,但我认为这三个文件的上下文很有帮助。谢谢!

编辑:SSCCE

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package palace.hero;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class SSCCE 
{
    public static void main(String[] args) 
    {    
        JPanel gridPanel = new JPanel();

        int xCoord = 0;
        int yCoord = 0;

        //Key Bindings        
        gridPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up");
        gridPanel.getActionMap().put("up", new SSCCEKA(xCoord, yCoord, "up"));
        gridPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down");
        gridPanel.getActionMap().put("down", new SSCCEKA(xCoord, yCoord, "down"));
        gridPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
        gridPanel.getActionMap().put("left", new SSCCEKA(xCoord, yCoord, "left"));
        gridPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");
        gridPanel.getActionMap().put("right", new SSCCEKA(xCoord, yCoord, "right"));

        //Window
        JFrame window = new JFrame("Window");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        int windowHeight = 1125;
        int windowWidth = 900;
        window.setPreferredSize(new Dimension(windowHeight, windowWidth));

        window.add(gridPanel);
        window.pack();
        window.setVisible(true);

        gridPanel.requestFocusInWindow();
    }
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package palace.hero;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class SSCCEKA extends AbstractAction
{
    String direction;
    int x = 0;
    int y = 0;

    public SSCCEKA(int x, int y, String direction) 
    {
        this.x = x;
        this.y = y;
    }

    @Override
    public void actionPerformed(ActionEvent ae) 
    {
        if(direction.toLowerCase().equals("up"))
        {
            x++;
        }
        if(direction.toLowerCase().equals("down"))
        {
            x--;
        }
        if(direction.toLowerCase().equals("left"))
        {
            y--;
        }
        if(direction.toLowerCase().equals("right"))
        {
            y++;
        }
    }
}

【问题讨论】:

  • 是按键检测不到还是其他的问题? (如果是这样,构造一个SSCCE 应该是微不足道的。)
  • 不,它们正在被检测到,我只是不知道如何让 AbstractAction 中的“actionPreformed”函数产生副作用。 (我已经让它打印“上,下,左,右”,但我希望它真正改变主类中的地板对象......)
  • 如果你能把你的问题归结起来会很有帮助...见How to create a Minimal, Complete, and Verifiable example
  • 修复了它。那么在这个例子中,我如何让键绑定影响主类中的 xcoord 和 yCoord?

标签: java swing multidimensional-array


【解决方案1】:

当您创建像游戏这样复杂的东西时,您应该使用model / view / controller pattern

那么,让我们创建一个模型类。

public class GameModel {

    private int xCoordinate;
    private int yCoordinate;

    public int getxCoordinate() {
        return xCoordinate;
    }

    public void setxCoordinate(int xCoordinate) {
        this.xCoordinate = xCoordinate;
    }

    public int getyCoordinate() {
        return yCoordinate;
    }

    public void setyCoordinate(int yCoordinate) {
        this.yCoordinate = yCoordinate;
    }

}

您可以通过构造函数将 GameModel 类传递给您的 SSCCEKA 类。

请记住,只有控制器类可以修改游戏模型。

【讨论】:

  • 抱歉这个新手问题,但是每次按下按钮时如何调用构造函数? (我真正要问的是如何允许 actionPressed 函数编辑游戏模型?)
  • @Haskelier:我假设您在谈论 GameModel 构造函数。您在 GUI 构造函数的开头调用它一次并将实例传递给 SSCCEKA 类,以便 actionPressed 方法可以访问 GameModel 实例。这是我写的Dice Game,它显示了模型/视图/控制器模式。
  • 它的工作!!!!十分感谢。我只需要在 KeyAction 类中创建一个 Gamemodel 实例。