【问题标题】:Java - KeyListener - KeyReleased sometimes doesn't triggerJava - KeyListener - KeyReleased 有时不会触发
【发布时间】:2016-07-03 04:42:28
【问题描述】:

我正在使用 Java 制作一个 2D 游戏,并且我有一个关键的监听器来处理玩家的动作和其他事情。它在大多数情况下都可以正常工作。但是,有时它会出现故障。例如,我将按住“A”键使角色向左移动,当我松开它时,角色会继续移动,就像我仍然按住键一样。我认为这是因为密钥侦听器由于某种原因没有检测到 keyReleased 事件。

我一直试图弄清楚为什么会这样,但仍然不知道为什么会这样。

如果您想看一下,这是我的代码的一部分。

按键监听类

package input;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import game.Game;

public class KeyboardInput extends KeyAdapter {
   public KeyboardInput() {
   }

   // Detects pressed keys
   public void keyPressed(KeyEvent e) {
      if (Game.init) {
         Keys.Keys[e.getKeyCode()] = true;
      }
   }

   // Detects released keys
   public void keyReleased(KeyEvent e) {
      if (Game.init) {
         Keys.Keys[e.getKeyCode()] = false;
      }
   } 
}

我的展示类的一部分

 // Display Constructor
public Display(String title, String gameVersion, int width, int height) {
  this.title = title;
  this.width = width;
  this.height = height;
  this.gameVersion = gameVersion;

  createDisplay();
}

// Creates display
private void createDisplay() {
  frame = new JFrame(title + " v. " + gameVersion);
  frame.setSize(width, height);
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.setResizable(false);
  frame.setLocationRelativeTo(null);
  frame.setVisible(true);
  frame.setFocusable(true);

  canvas = new Canvas();
  canvas.setPreferredSize(new Dimension(width, height));
  canvas.setMinimumSize(new Dimension(width, height));
  canvas.setMaximumSize(new Dimension(width, height));
  canvas.setBackground(Color.WHITE);

  frame.add(canvas);
  frame.addKeyListener(new KeyboardInput()); // ADDING KEY LISTENER TO THE JFRAME
  canvas.addMouseListener(new MouseInput());
  frame.pack();
  if (frame.getKeyListeners().length > 0) {
    System.out.println("Key listener initialized");
  } else {
    System.out.println("ERROR : Key listener couldn't initialize");
  }
  if (canvas.getMouseListeners().length > 0) {
    System.out.println("Mouse listener initialized");
  } else {
    System.out.println("ERROR : Mouse listener couldn't initialize");
  }
}

// Updates display (called every frame)
public void update() {
  frame.requestFocus();
  tick++;
  lasttime = currtime;
  currtime = System.nanoTime();
  delta = (currtime - lasttime) / 1000000000;
  fps = (float) (1 / delta);
  if ((tick / fps) >= SAVE_TIME) {
    tick = 0;
    saveNextTick = true;
    System.out.println("FPS = " + Math.round(getFPS()));
    try {
      System.out.println("MOUSE POSITION = (" + frame.getMousePosition().getX() + ", "
        + frame.getMousePosition().getY() + ")");
    } catch (Exception e) {
      System.out.println("Mouse out of screen. Could not get mouse position (NullPointerException)");
    }
  }

  if (saveNextTick) {
    Save.saveGame("Save");
    saveNextTick = false;
  }
}

处理玩家移动的方法

private void checkMove() {
   int speed = moveSpeed;
   int x1 = getxPos();
   int x2 = x1 + getTexture().getImage().getWidth();
   int y1 = getyPos();
   int y2 = y1 + getTexture().getImage().getHeight();
   if ((Keys.Keys[KeyEvent.VK_W] || Keys.Keys[KeyEvent.VK_S]) &&       (Keys.Keys[KeyEvent.VK_A] || Keys.Keys[KeyEvent.VK_D])) {
      speed = diagonalMoveSpeed;
   }
   int d = Math.max((int) (speed / Display.getFPS()), 1);
   if (speed / Display.getFPS() < 1 && Util.randInt(0, 100) > speed /  Display.getFPS() * 100) {
      d = 0;
   }
   if (Keys.Keys[KeyEvent.VK_W] && !States.currentState.checkCollision(x1,  x2, y1 - d, y2 - d)) {
      move(0, -d);
   }
   if (Keys.Keys[KeyEvent.VK_A] && !States.currentState.checkCollision(x1 - d, x2 - d, y1, y2)) {
      move(-d, 0);
   }
   if (Keys.Keys[KeyEvent.VK_S] && !States.currentState.checkCollision(x1, x2, y1 + d, y2 + d)) {
      move(0, d);
   }
   if (Keys.Keys[KeyEvent.VK_D] && !States.currentState.checkCollision(x1 + d, x2 + d, y1, y2)) {
      move(d, 0);
   }
}

提前感谢您的帮助。如果您需要查看代码的任何其他部分来找出问题所在,请询问。

附: :我知道这可能不是编写按键监听器/获取键盘输入的最简单方法,但这是我知道的唯一方法。我目前正在寻找一种更好的方法,一旦找到我就会改变它。

【问题讨论】:

  • 你能发布你的关键课程吗?或根据按键输入处理移动的类
  • 当然!我已经编辑了我的原始帖子。此外,我稍微更改了关键侦听器类。我没想到它会解决问题,但这只是一种更简单的方法。另外,我认为问题可能是我的键盘是垃圾并且按键一直卡住。我记得有时我在其他游戏中遇到过这个问题。我将尝试在另一台计算机上对其进行测试,看看是否能解决问题。
  • 当你松开按键时,通过打印语句检查按键事件是否仍在触发。这将告诉您您的键类(我怀疑)或您的键盘是否有问题。
  • 好的,谢谢,我试试看。

标签: java keylistener


【解决方案1】:

你应该做一些类似键盘去抖动的事情。因为当我们长时间按下键盘按钮时。因为当我们尝试在编辑器中通过长按键盘键来编写文本时,释放键后会生成更多字符。

阅读对应的QA:
implementing debounce in Java

【讨论】:

  • 感谢您的帮助,但这看起来并没有解决我的问题。
猜你喜欢
  • 2014-09-17
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 2013-01-23
  • 2013-06-04
  • 2012-12-11
  • 2011-07-09
  • 1970-01-01
相关资源
最近更新 更多