Java:如何在不检查每个循环的情况下检测某个键是否被按下超过一定时间

标签 java timing keyevent

编辑:请注意其他人,过早的优化是万恶之源!如果我没有忙着尝试优化代码的各个方面(这是一个不错的阶段!),我就会编写一个漂亮的、可读的程序,可以由其他人维护和理解。


每个循环(1/60秒)Player类都会检查Game类以查看哪个键被按下,如果玩家没有面向正确的方向,它就会转向正确的方向,否则它会朝那个方向移动.

遗憾的是,这意味着如果您想转动而不移动,则必须点击按键少于 2/60 秒(两次循环)。检查按下哪个键的代码如下 下面是完整源代码和构建示例的链接。

public class Game extends RenderableObject
{
    public static final byte NONE = 0;
    public static final byte UP = 1;
    public static final byte RIGHT = 2;
    public static final byte DOWN = 3;
    public static final byte LEFT = 4;

    public byte key = NONE;

    public Game()
        {
        }

    @Override
    public void keyPressed(KeyEvent ke)
        {
            if (!paused)
                {
                    if (ke.getKeyCode() == 38) // '^ key'
                        {
                            key = UP;
                            return;
                        }
                    else if (ke.getKeyCode() == 40) // 'v key'
                        {
                            key = DOWN;
                            return;
                        }
                    if (ke.getKeyCode() == 37) // '< key'
                        {
                            key = LEFT;
                            return;
                        }
                    else if (ke.getKeyCode() == 39) // '> key'
                        {
                            key = RIGHT;
                            return;
                        }
                }
        }

    @Override
    public void keyReleased(KeyEvent ke)
        {
            if (ke.getKeyCode() == 38) // '^ key'
                {
                    if (key == UP)
                        key = NONE;
                    return;
                }
            else if (ke.getKeyCode() == 40) // 'v key'
                {
                    if (key == DOWN)
                        key = NONE;
                    return;
                }
            if (ke.getKeyCode() == 37) // '< key'
                {
                    if (key == LEFT)
                        key = NONE;
                    return;
                }
            else if (ke.getKeyCode() == 39) // '> key'
                {
                    if (key == RIGHT)
                        key = NONE;
                    return;
                }

        }

完整源代码和构建示例的链接:(无论如何,还有一个带有下载链接的页面链接!

警告:我是个菜鸟,如果我的命名约定不正确...请不要伤害我!

http://troygametwodee.blogspot.com/2011/09/latest-build-21092011.html

所以我已经尝试过一些想法,但没有一个看起来特别优雅,而且很快就变得非常困惑,

我理想地希望能够在游戏类中检查某种 boolean 值,这样玩家只有在 boolean 值为真时才朝那个方向移动,但我也失败了:(

因此,如果有人有任何建议,我会非常高兴:)

提前致谢

最佳答案

好吧,那么我如何在保持流畅运动的同时解决这个问题:

首先,我添加了一个名为“held”的 boolean 变量。这本身是没有用的,所以我还添加了 一个数值变量,称为“timeHeld”。每次按下一个键时,我都会将“timeHeld”重置为零,并使“held”== false,并将以下代码放入我的循环中。

if (timeHeld < 20)
    timeHeld++;
else
    held = true;

因此,在我的玩家类中,当决定以哪种方式移动时,它会调用“Game.key”来评估哪个键被按下,然后如果“held” boolean 值为真(在三分之一秒后)玩家朝那个方向行走,否则玩家会停留在屏幕上的位置,只是改变了它所看的方向。

这在一定程度上有效,但每次我改变方向时,“hold”变量都会再次设置为零。这意味着每次我转身都会延迟三分之一秒,非常烦人!

所以我这样做了:

if (ke.getKeyCode() == 38) // '^ key'
        {
            if (key == NONE)
                {
                    held = false;
                    timeHeld = 0;
                }
            key = UP;
            return;
    }

这意味着只要按下箭头键,“按住”就保持不变,因此一旦玩家开始移动,转弯时就不会出现延迟。

这绝对完美地工作,所以这就是答案,但是我还添加了另一个变量。因为当我使用箭头键或“wasd”键演奏时,我只使用中指来操作向上和向下键,所以当我从北向南切换时,我最终会放开所有键。在这种情况下,使用如上所述的代码,我最终停止了三分之一秒,所以为了解决这个问题,我添加了一个名为“延迟”的变量

当松开一个键时,延迟设置为 10(循环),每个循环我调用:

if (delay > 0)
    delay--;

然后当按下一个键时我调用:

if (ke.getKeyCode() == 38) // '^ key'
    {
        if (key == NONE && delay == 0)
                {
                    held = false;
                        timeHeld = 0;
                }
            key = UP;
            return;
        }

这意味着只有当按下方向键并且按下方向键时没有其他方向键且延迟为 0 时,“hold”才会设置为 false。这给了我在放手之间有 10 个循环延迟的所有箭头键,并在“hold”设置为 false 之前按另一个箭头键。

感到困惑吗?我是!但它有效,任何其他遇到此问题的人都可以点击我的博客的链接,该博客应该有最新的工作源代码,或者只是要求我解释您没有得到的部分:D

关于Java:如何在不检查每个循环的情况下检测某个键是否被按下超过一定时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7499417/

相关文章:

java - 复选框 - CSS 效果不起作用

javascript - 如何在 Javascript 中对循环的不同部分进行计时

ios - 谷歌分析时间未显示

sql - 获取 PostgreSQL 查询的执行时间

java - Android:如何使用 if 语句来获取 bundle/Intent 值?

java - 在 GCViewer 的帮助下调整垃圾收集器

forms - Access 2007 表格 : event AFTER undo

java 。忽略/禁用按键功能但仍捕获按键事件

java - 无需递归即可获取结构中的文件数