I'm more-or-less done with my first game and I'm thinking about a second. This would use keys, and I want to ensure that the key handling code is thread-safe. The topic of handling keys is discussed a bit in the tips thread, but I don't want to pollute that one, hence this thread. It might be appropriate to link to this thread, or a post in it, from that one once the dust settles.
The issue I have is this: the standard key handling discussed there is basically to detect key pressed and released events and update a boolean. That's fine if my game logic only cares whether keys are up or down, but not so fine if I care about detecting key presses: e.g. for jumping. If the pressed and released events both occur before the logic call then the character won't jump and may meet a frustrating doom.
My idea for approaching this is to borrow a trick from lock-free synchronisation (e.g. lock-free single-producer single-consumer, which is essentially what we have here: an event thread which produces events and another thread which does updates and probably renders). I would be grateful for critiques and improvements on this implementation, and suggestions of cheaper ways to obtain the same result.
public class Game4k extends Applet
private static final int NUM_KEYS = 0x10000;
private int keyEventCount = new int[NUM_KEYS];
public void start()
int prevKeyEventCounts = new int[NUM_KEYS];
int keyDown = new int[NUM_KEYS];
int keyPressed = new int[NUM_KEYS];
for (int i = 0; i < NUM_KEYS; i++)
int eventCount = keyEventCount[i];
keyDown[i] = eventCount & 1;
int delta = eventCount - prevKeyEventCounts[i];
keyPressed[i] = (delta / 2) + (delta & eventCount);
prevKeyEventCounts[i] = eventCount;
public void processKeyEvent(KeyEvent evt)
int id = evt.getID() & 3;
if (id != 0)
Ideally I'd like to debounce both keyDown and keyPressed as well, to work around the issue with some window managers (e.g. KDE) doing auto-repeat. However, there's no sure-fire way of telling whether multiple key presses come from the user or the WM, so I think I'll have to live with that issue.