Java中的键绑定:按键后延迟

Java中的键绑定:按键后延迟,java,swing,awt,key-bindings,Java,Swing,Awt,Key Bindings,编辑:从游戏中添加代码 我有一个游戏的键绑定,我正在工作。他们应该在按键时移动物体 (当前,每个println(..)表示在屏幕上移动内容的实际代码,稍后将添加) 控制台中的打印工作正常,但会出现延迟。“左”、“右”等字样在控制台中延迟出现,有时延迟半秒,有时延迟几秒 有时根本没有延迟,但当一个接一个地按下许多键时,会有几秒钟的延迟,只有在这时,这些字才会出现在控制台中(就像计算机在同一时间处理太多的内容一样) 当我在另一个项目中进行相同的键绑定时,没有所有的游戏逻辑,只按控制台中打印单词的按钮

编辑:从游戏中添加代码

我有一个游戏的键绑定,我正在工作。他们应该在按键时移动物体

(当前,每个println(..)表示在屏幕上移动内容的实际代码,稍后将添加)

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

有时根本没有延迟,但当一个接一个地按下许多键时,会有几秒钟的延迟,只有在这时,这些字才会出现在控制台中(就像计算机在同一时间处理太多的内容一样)

当我在另一个项目中进行相同的键绑定时,没有所有的游戏逻辑,只按控制台中打印单词的按钮——它毫不延迟地完美工作

所以我怀疑问题在于游戏代码,或者我在游戏代码中使用密钥绑定的方式

我该如何解决这个问题

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

下面是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();
        }

    }
}
import java.util.*;
导入java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
公共类板扩展JPanel实现Runnable{
储罐1、储罐2;
布尔[]键按1,键按2;
动作upAction、leftAction、rightAction、WaAction、aAction、dAction;
InputMap InputMap;
行动地图;
公共委员会(){
设置聚焦(真);
挫折背景(颜色:黑色);
储罐1=新储罐(“红色”);
储罐2=新储罐(“蓝色”);
inputMap=this.getInputMap();
actionMap=this.getActionMap();
线程gameloop=新线程(此);
gameloop.start();
}
公共组件(图形g){
超级组件(g);
Graphics2D g2d=(Graphics2D)g;
//在屏幕上绘制坦克。
}
公开募捐{
//密钥绑定//////
upAction=newAbstractAction(){
已执行的公共无效操作(操作事件e){
System.out.println(“up”);
}
};
leftAction=新的AbstractAction(){
已执行的公共无效操作(操作事件e){
系统输出打印项次(“左”);
}
};
rightAction=新的AbstractAction(){
已执行的公共无效操作(操作事件e){
System.out.println(“右”);
}
};
WAAction=新的AbstractAction(){
已执行的公共无效操作(操作事件e){
系统输出打印项次(“w”);
}
};
aaAction=newAbstractAction(){
已执行的公共无效操作(操作事件e){
系统输出打印项次(“a”);
}
};
dAction=newAbstractAction(){
已执行的公共无效操作(操作事件e){
系统输出打印号(“d”);
}
};
inputMap.put(KeyStroke.getKeyStroke(“UP”),“upAction”);
inputMap.put(KeyStroke.getKeyStroke(“左”),“leftAction”);
inputMap.put(KeyStroke.getKeyStroke(“右”),“rightAction”);
inputMap.put(KeyStroke.getKeyStroke(“W”),“WaAction”);
inputMap.put(KeyStroke.getKeyStroke(“A”),“AAAction”);
inputMap.put(KeyStroke.getKeyStroke(“D”),“dAction”);
动作图。放置(“upAction”,upAction);
actionMap.put(“leftAction”,leftAction);
actionMap.put(“rightAction”,rightAction);
动作图。放置(“动作”,动作);
动作图。放置(“aaaction”,aaaction);
动作图。放置(“dAction”,dAction);
//结束键绑定//////
//开始游戏循环////
每秒整数滴答数=50;
int SKIP_TICKS=1000/TICKS_/s;
int MAX_FRAMESKIP=10;
long next_game_tick=System.currentTimeMillis();
int循环;
布尔博弈_is _running=true;
同时(游戏正在运行){
循环=0;
while(System.currentTimeMillis()>next\u game\u tick&loops
感谢您的帮助

  • 您正在使用Swing事件线程或EDT执行大量Swing调用。如果你想谨慎(相信我,是的),不要这样做
  • 当按下一个键时,您依赖操作系统来执行重复操作,操作系统的行为是在重复之前先暂停
  • 您需要在按键时启动摆动计时器,然后在按键上升时将其关闭或更改其状态。这可能会解决你的问题

如果这无济于事,再考虑创建和发布一个.< /P>,考虑一下发布一个更好的帮助。如果你告诉我们你游戏代码的重要部分(你确切地把你的密钥绑定代码放在哪里以及如何放置),我们会更容易回答你的问题。。可能发生了一些事情,这意味着线程没有立即执行它,但您在此处发布的代码基本上是无关的-我们需要查看SSCCE以进一步提供帮助。我对问题进行了重要编辑,只发布了(我认为)相关的代码。帮助将不胜感激:)我们可以编译和运行您的代码未经修改?不,所以这不是一个SSCCE,我们中的许多人将无法提供帮助。如果你不能很快得到答案,考虑创建和发布你的SCSCE。“Swing调用”是指,任何影响Swing组件的命令?如果是,唯一的“软件