如何消除关键preSS延迟? [英] How to eliminate delay in keyPress?
问题描述
所以,我已经看到这个几个线程,我需要如何具体解决它一定的帮助。当您按住一个键,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屋!