如何消除关键preSS延迟? [英] How to eliminate delay in keyPress?

查看:158
本文介绍了如何消除关键preSS延迟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我已经看到这个几个线程,我需要如何具体解决它一定的帮助。当您按住一个键,Java将读取的第一个关键preSS,然后会有一个小的延迟,然后直到你松开按键将连续读取的关键preSS。

So I have seen a few threads about this already and I need some help about how to fix it specifically. When you hold down a key, Java will read the first key press, then there will be a small delay, and then it will continuously read the key press until you release the key.

public void keyPressed(KeyEvent key) {
    int code = key.getKeyCode();
    if (code == KeyEvent.VK_DOWN) {
        //Do stuff
    }
    if (code == KeyEvent.VK_LEFT) {
        //Do stuff
    }
    if (code == KeyEvent.VK_RIGHT) {
        //Do stuff
    }
    if (code == KeyEvent.VK_UP) {
        //Do stuff
    }
}

这是我目前的code。听说要解决这个问题,你可以创建一个定时器,快速检查重点presses,但我真的不知道该怎么做。将AP preciate一些帮助这里或是否有更好的解决方案。

That is my current code. I heard that to fix this you can create a timer which rapidly checks for key presses, but I'm not really sure how to do that. Would appreciate some help here or if there is a better solution.

推荐答案

基本的回答你的问题是,你不能,延迟特定的操作系统

The basic answer to your question is, you can't, the delay is OS specific.

较长的答案是,你应该忽略个别事件本身和监控状态通过使用相应的标志的变化(preSS和释放之间)。

The longer answer is, you should be ignoring the individual events themselves and monitor a change in state (between press and release) through the use of appropriate flags.

这意味着,当一个关键是pressed,你设置一些标志,你的程序可以用它来改变程序的状态,释放时,你重新设置。

This means, that when a key is pressed, you set some flag which you program can use to change the state of the program and when released, you reset it.

这从解除关联状态改变事件并为您提供更多的灵活性,因为你的程序不关心什么引起的状态变化,只有国家已经改变了,应该对其做出反应。

This disassociates the event from state change and provides you with much more flexibility, as your program doesn't care what caused the state change, only that the state has changed and it should react to it.

这会要求你有某种循环,其职责是的,是监测这一变化,并作出相应的反应吧。在游戏中,这通常被称为游戏环,但也可以被称为主循环

This will require you to have some kind of "loop" whose responsibility it is, is to monitor this change and react to it accordingly. In gaming, this is commonly known as a "game-loop", but can also been known as "main-loop".

正是这种循环负责更新程序的状态,并把它画。

It's this "loops" responsibility to update the state of the program and get it painted.

下面是一个使用键绑定API javax.swing.Timer中的 证明的基本概念

Below is a very simple example which uses the key bindings API and a javax.swing.Timer to demonstrate the basic concepts

import com.sun.glass.events.KeyEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MoveMe {

    public static void main(String[] args) {
        new MoveMe();
    }

    public MoveMe() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MovementState {

        public int xDirection;
        public int yDirection;

    }

    public class TestPane extends JPanel {

        private MovementState movementState;
        private Rectangle box;

        public TestPane() {
            movementState = new MovementState();
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down-pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down-released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up-pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up-released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left-pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left-released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right-pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right-released");

            am.put("down-pressed", new YDirectionAction(movementState, 2));
            am.put("down-released", new YDirectionAction(movementState, 0));
            am.put("up-pressed", new YDirectionAction(movementState, -2));
            am.put("up-released", new YDirectionAction(movementState, 0));
            am.put("left-pressed", new XDirectionAction(movementState, -2));
            am.put("left-released", new XDirectionAction(movementState, 0));
            am.put("right-pressed", new XDirectionAction(movementState, 2));
            am.put("right-released", new XDirectionAction(movementState, 0));

            box = new Rectangle(90, 90, 20, 20);

            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    box.x += movementState.xDirection;
                    box.y += movementState.yDirection;
                    if (box.x < 0) {
                        box.x = 0;
                    } else if (box.x + box.width > getWidth()) {
                        box.x = getWidth() - box.width;
                    }
                    if (box.y < 0) {
                        box.y = 0;
                    } else if (box.y + box.height > getHeight()) {
                        box.y = getHeight() - box.height;
                    }
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.RED);
            g2d.fill(box);
            g2d.dispose();
        }
    }

    public abstract class AbstractDirectionAction extends AbstractAction {

        private final MovementState movementState;
        private final int value;

        public AbstractDirectionAction(MovementState movementState, int value) {
            this.movementState = movementState;
            this.value = value;
        }

        public MovementState getMovementState() {
            return movementState;
        }

        public int getValue() {
            return value;
        }

    }

    public class YDirectionAction extends AbstractDirectionAction {

        public YDirectionAction(MovementState movementState, int value) {
            super(movementState, value);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            getMovementState().yDirection = getValue();
        }

    }

    public class XDirectionAction extends AbstractDirectionAction {

        public XDirectionAction(MovementState movementState, int value) {
            super(movementState, value);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            getMovementState().xDirection = getValue();
        }

    }

}

这篇关于如何消除关键preSS延迟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆