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

时间:2014-01-02 19:04:08

标签: java swing awt key-bindings

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

我为我正在进行的游戏获得了Key Bindings。他们应该在按下按键时移动物体。

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

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

有时候没有任何延迟,但是当一个接一个地按下很多按键时,会有几秒的延迟,然后只有这些字出现在控制台中(就像计算机有太多不能处理的那样)同时)。

当我在没有所有游戏逻辑的情况下在不同项目中执行相同的键绑定时,只需按下在控制台中打印文字的按钮 - 它可以毫不拖延地完美运行。

所以我怀疑问题与游戏代码有关,或者我在游戏代码中使用Key Bindings的方式。

我该如何解决这个问题?

我尝试将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();
        }

    }
}

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

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

如果这没有帮助,请再次考虑投入努力创建和发布sscce