比游戏循环更快地检查按键

时间:2017-03-22 17:44:48

标签: java swing user-interface timer

我有一个名为Activity的课程,其扩展为JPanel

我的问题是我希望Activity每1000毫秒运行游戏循环(更新其字段和GUI等),但始终要检查(以便响应)按键。

private final BitSet keys = new BitSet(256);
...

public void keyPressed(final KeyEvent e) {
    keys.set(e.getKeyCode()); 
}

public void keyReleased(final KeyEvent e) {
    keys.clear(e.getKeyCode());
}

...

public void actionPerformed(ActionEvent e) {
  processKeys(); // Checks keys
  processData(); // Main game loop
  repaint();     // Draws game components
}

目前,该课程按键存储BitSet并且每1000毫秒,actionPerformed()查看按下的键(如按下右箭头右侧的移动玩家位置),处理主游戏循环东西(如果边界被击中则结束游戏),并按顺序重新绘制屏幕。

问题是我必须在计时器触发前按一个键才能检测到它,否则它会在BitSet被调用的时候被processKeys()删除。我仍然希望游戏循环每隔1000毫秒运行一次。

我考虑过

  1. 创建2个同步计时器 - 游戏循环1000毫秒,按键分析1毫秒
  2. 设置定时器我需要1ms,并使用类字段来跟踪定时器触发。检查按键每次触发,只在fires % 1000 == 0
  3. 时运行游戏循环/重绘

    我不确定#1是否会导致性能问题或导致计时器差异,我很确定#2是不可靠的,因为当我尝试它时,通常该字段从未达到1000或2000等等。

    解决方案是什么?

1 个答案:

答案 0 :(得分:3)

正如您似乎已经发现的那样,由于按下按键与处理按键之间的延迟时间很长,因此可以在处理密钥之前将其从BitSet中删除。

相反,有两个BitSet s,一个用于按下,一个用于释放按键,在您处理完按键后,从“按下的按键”设置中删除“已释放按键”设置中的所有项目,重置“释放键”设置并继续。

当然,这假设您希望在进程循环之间的1秒延迟期间处理键入的任何键。

另一个选择可能是实时处理关键事件,将它们的效果应用于某种“改变状态”,这种状态可以在进程循环发生时应用于实际模型,但是相同的东西