【问题标题】:Key Bindings in Java: Delay after key pressJava中的键绑定:按键后延迟
【发布时间】:2014-01-03 05:09:23
【问题描述】:

编辑:从游戏中添加代码。

我为我正在开发的游戏获得了键绑定。它们应该在按下键时移动对象。

(目前每个 println(..) 都代表了在屏幕上移动东西的实际代码,稍后会添加)。

控制台中的打印工作正常,但有延迟。 “左”、“右”等字样在控制台中出现延迟,有时延迟半秒,有时延迟几秒。

有时根本没有延迟,但是当很多键一个接一个地按下时,会有几秒钟的延迟,然后控制台中才会出现单词(就像计算机有太多要处理的东西一样)同一时间)。

当我在没有所有游戏逻辑的不同项目中执行相同的键绑定时,只在控制台中按下打印单词的按钮 - 它完美无延迟地工作。

所以我怀疑问题出在游戏代码上,或者我在游戏代码中使用键绑定的方式。

我该如何解决这个问题?

我尝试将 Key Bindings 代码放入包含游戏循环的线程(在游戏循环之前)和构造函数中。同样的问题。

这里是Board类(扩展JPanel)的相关代码,它是游戏的主要JPanel,显示图形和操作对象。

import java.util.*;
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class Board extends JPanel implements Runnable {

    Tank tank1,tank2;
    boolean[] keysPressed1,keysPressed2;
    Action upAction,leftAction,rightAction,wAction,aAction,dAction;
    InputMap inputMap;
    ActionMap actionMap;

    public Board(){

        setFocusable(true);
        setBackground(Color.BLACK);

        tank1 = new Tank("red");
        tank2 = new Tank("blue");

        inputMap = this.getInputMap();
        actionMap = this.getActionMap();

        Thread gameloop = new Thread(this);
        gameloop.start();

    }

    public void paintComponent(Graphics g){

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        // Drawing tanks on the screen.

    }

    public void run(){

        // Key Bindings //////

        upAction = new AbstractAction(){
            public void actionPerformed(ActionEvent e){
                System.out.println("up");
            }
        };

        leftAction = new AbstractAction(){
            public void actionPerformed(ActionEvent e){
                System.out.println("left");
            }
        };

        rightAction = new AbstractAction(){
            public void actionPerformed(ActionEvent e){
                System.out.println("right");
            }
        };

        wAction = new AbstractAction(){
            public void actionPerformed(ActionEvent e){
                System.out.println("w");
            }
        };

        aAction = new AbstractAction(){
            public void actionPerformed(ActionEvent e){
                System.out.println("a");
            }
        };

        dAction = new AbstractAction(){
            public void actionPerformed(ActionEvent e){
                System.out.println("d");
            }
        };

        inputMap.put(KeyStroke.getKeyStroke("UP"),"upAction");
        inputMap.put(KeyStroke.getKeyStroke("LEFT"),"leftAction");
        inputMap.put(KeyStroke.getKeyStroke("RIGHT"),"rightAction");
        inputMap.put(KeyStroke.getKeyStroke("W"),"wAction");
        inputMap.put(KeyStroke.getKeyStroke("A"),"aAction");
        inputMap.put(KeyStroke.getKeyStroke("D"),"dAction");

        actionMap.put("upAction",upAction);
        actionMap.put("leftAction",leftAction);
        actionMap.put("rightAction",rightAction);
        actionMap.put("wAction",wAction);
        actionMap.put("aAction",aAction);
        actionMap.put("dAction",dAction);

            // End Key Bindings //////

            // Start of game loop. ////

        int TICKS_PER_SECOND = 50;
        int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
        int MAX_FRAMESKIP = 10;

        long next_game_tick = System.currentTimeMillis();
        int loops;

        boolean game_is_running = true;

        while( game_is_running ) {

            loops = 0;
            while( System.currentTimeMillis() > next_game_tick && loops < MAX_FRAMESKIP) {

                    // Code to manipulate tank1.
                    // .......

                tank1.move();

                    // Code to manipulate tank2.
                    // .......

                tank2.move();

                next_game_tick += SKIP_TICKS;
                loops++;
            }

            repaint();
        }

    }
}

感谢您的帮助

【问题讨论】:

  • 考虑发布SSCCE 以获得更好的帮助。
  • 如果您向我们展示了游戏代码的重要部分(您在 Key Bindings 代码中的确切位置和方式),我们会更容易回答您的问题。
  • 可能发生了一些事情,这意味着线程没有立即执行它,但是您在此处发布的代码在很大程度上是无关紧要的 - 我们需要查看 SSCCE 以进一步提供帮助。
  • 我对问题进行了重大编辑,只发布了(我认为的)相关代码。帮助将不胜感激:)
  • 我们可以原封不动地编译和运行您的代码吗?不,所以这不是 SSCCE,我们中的许多人将无法提供帮助。如果您没有很快得到答复,请考虑创建并发布您的 SSCCE。

标签: java swing awt key-bindings


【解决方案1】:
  • 您正在从 Swing 事件线程或 EDT 执行大量 Swing 调用。如果您想谨慎行事(您愿意,相信我),请不要这样做。
  • 您依赖操作系统在按住某个键时执行重复操作,而操作系统的行为是在重复之前先暂停。
  • 您需要在按键时启动 Swing Timer 并在按键抬起时将其关闭或更改其状态。这可能会解决您的问题。

如果这没有帮助,请再次考虑创建并发布sscce

【讨论】:

  • “swing 调用”是指影响 Swing 组件的任何命令?如果是这样,我发现的唯一“摇摆调用”是这些: setFocusable(true);设置背景(颜色。黑色);还有吗?
  • 确实存在您所说的内置延迟,但不仅如此。我将其编辑为问题:“有时根本没有延迟,但是当一个接一个地按下很多键时,会有几秒钟的延迟,然后才会出现在控制台中的单词(就像计算机有太多了,无法同时处理)。”就好像程序对电脑的要求太高,电脑打印不出“左”、“右”等字样。有时毫不拖延。知道如何解决这个问题吗?
猜你喜欢
  • 2012-07-18
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多