I’ve made a little demo that shows that the input handling in Java 6 seems to freeze at times. Although I’m using a rather perculiar input-handling schema, it is not the source of the problem (works fine in Java 5).
It seems that events get bottlenecked somewhere, and then they start to flow again. As you can see in my application, the ACTIONS text contains a integer defining what keys are currently pressed…they sometimes get “stuck” at some value.
The application ran fine in many cases, but as I kept running it, I kept noticing this “input lag”. It’s like the application stutters.
(If you don’t get it, try running it, close it, and run it again immediatly).
My test application (a basic template for a 4k game):
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Transparency;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JFrame;
public class InputTest extends JFrame {
static final int W = 1024;
static final int H = 768;
static int ACTIONS = 0;
static final int A_LEFT = 1;
static final int A_RIGHT = 2;
static final int A_FORWARD = 4;
static final int A_REVERSE = 8;
static final int A_MOVERIGHT = 16;
static final int A_MOVELEFT = 32;
static final int A_WARP = 64;
static final int[] GRAP_KEY_TYPES = {A_FORWARD,A_MOVELEFT,A_REVERSE,A_MOVERIGHT,A_WARP};
static final int[] GRAP_KEY_EVENTS = { KeyEvent.VK_W, KeyEvent.VK_A, KeyEvent.VK_S, KeyEvent.VK_D, KeyEvent.VK_E} ;
public InputTest() {
setTitle("Input Test");
setSize(W,H);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
enableEvents(AWTEvent.KEY_EVENT_MASK|AWTEvent.MOUSE_EVENT_MASK);
show();
createBufferStrategy(2);
BufferStrategy strategy = getBufferStrategy();
Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
long lastLoopTime = System.nanoTime();
int frames = 0;
int acc = 0;
int fps = 0;
int MOUSE_X = 0, MOUSE_Y = 0;
Random rand = new Random(System.nanoTime());
BufferedImage background = new BufferedImage(W,H,Transparency.OPAQUE);
((Graphics2D)background.getGraphics()).setBackground(Color.BLACK);
while(true) {
acc += (System.nanoTime() - lastLoopTime) / 1000000f;
lastLoopTime = System.nanoTime();
if(acc >= 1000) {
acc -= 1000;
fps = frames;
frames = 0;
}
frames++;
try {
MOUSE_X = getMousePosition().x;
MOUSE_Y = getMousePosition().y;
} catch(Exception e) {
}
g.drawImage(background,0,0,null);
g.setColor(Color.darkGray);
for(int i = 0; 100 > i; i++) {
g.drawRect(rand.nextInt(W),rand.nextInt(H),10,10);
}
g.setColor(Color.WHITE);
g.drawString("Actions: " + ACTIONS, 100, 100);
g.drawString("FPS: " + fps, 250,100);
g.drawString("Mouse: " + MOUSE_X+","+MOUSE_Y, 450,100);
strategy.show();
if (!isVisible()) {
System.exit(0);
}
}
}
public static void main(String[] args) {
new InputTest();
}
protected void processKeyEvent(KeyEvent e) {
for(int i = 0; GRAP_KEY_EVENTS.length > i; i++) {
if(e.getKeyCode() == GRAP_KEY_EVENTS[i]) {
ACTIONS|=(e.getID()==KeyEvent.KEY_PRESSED)?GRAP_KEY_TYPES[i]:0;
ACTIONS^=(e.getID()==KeyEvent.KEY_RELEASED)?GRAP_KEY_TYPES[i]:0;
break;
}
}
}
protected void processMouseEvent(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) {
ACTIONS|=(e.getID()==MouseEvent.MOUSE_PRESSED)?A_LEFT:0;
ACTIONS^=(e.getID()==MouseEvent.MOUSE_RELEASED)?A_LEFT:0;
}
else if(e.getButton() == MouseEvent.BUTTON3) {
ACTIONS|=(e.getID()==MouseEvent.MOUSE_PRESSED)?A_RIGHT:0;
ACTIONS^=(e.getID()==MouseEvent.MOUSE_RELEASED)?A_RIGHT:0;
}
}
}