java swing keylistener 2d boulderdash

我正在寻找一个巨石问题,但首先我只是想让玩家四处走动,他被允许移动到任何不是摇滚(1)或墙(0)的空间。

我的向上和向左运动工作正常,但是正确和向下都被搞砸了,即使按键只按一次,它们也会移动多个空格。 这是一个可视化,如果它有帮助,我发布所有相关的代码,但我猜这个bug是在他的keylistener部分

这是我在另一个网站http://textuploader.com/13k1上传的代码

我花了几分钟试图复制粘贴代码在这里,但代码function,但不是所有的代码被分类为代码,我不允许提交它

以下是其他相关类和文件的链接

  • http://www.scs.ryerson.ca/~ikokkari/BDTile.java
  • http://www.scs.ryerson.ca/~ikokkari/BDLevelReader.java
  • http://www.scs.ryerson.ca/~ikokkari/levels.xml

首先,永远不要使用数字常量而不是字段常量,

 public void keyPressed(KeyEvent k) { int keyCode = k.getKeyCode(); if(keyCode == KeyEvent.VK_R) // not keyCode == 82 } 

更好的方法是使用InputMap和ActionMap,我认为它也称为“Key Binding”(由MadProgrammer建议)。 输入映射将键击映射到操作名称,操作映射将操作名称映射到您要执行的操作。

替换你的行(以及整个KeyListener扩展类)

 this.addKeyListener(new MyKeyListener()); 

有类似的东西

 this.getInputMap().put(KeyStroke.getKeyStroke("control L"), "link"); 

您需要在哪里参考KeyStroke.getKeyStroke的文档来修改指定的击键以满足您的需要。 在我的示例中,“link”是按下CTRL + L时要采取的操作的名称。 现在我们需要指定“链接做什么”

 this.getActionMap().put("link", new LinkAction()); 

其中LinkAction是我的类,它扩展了AbstractAction ,在你的情况下应该包括你的方法,如levelReaderObject.setCurrentLevel(presentLevel);

请注意,您不需要为每个键创建一个Action。 对于移动(向上,向下,向左,向右),我会将所有移动按钮绑定到不同的动作名称(“向上移动”等),但是然后将所有动作名称映射到相同的动作并让方法进入该动作做的工作:

 this.getActionMap().put("move up", new MoveAction(0)); this.getActionMap().put("move down", new MoveAction(1)); this.getActionMap().put("move right", new MoveAction(2)); this.getActionMap().put("move left", new MoveAction(3)); 

 class MoveAction extends AbstractAction { int direction; public MoveAction (int direction) { this.direction = direction; } @Override public void actionPerformed(ActionEvent e) { switch(direction) // perform the action according to the direction } } 

请注意,我将移动操作分组在一起的建议是一个设计决策,您应该自己决定如何构建绑定(您可以对一切使用一个操作或为每个操作使用一个操作)。