InputHandler help ?

Hello guys, I just registered here, to ask you a question.

I’m trying to make input handler, and I’m using keys[e.getKeyCode] etc for it.

My question is, how to make isKeyPressed method, where it detects if key is pressed, but returns true just once ?

For example, I have int variable number. When I press and hold key space, it should add 1 to number, but only once, no matter how long i hold the spacebar.

I hope you can help me !

Hey PixelDeBurner and welcome to JGO!

The best way to do this is to put all key codes you get from the keyPressed method into a HashSet, removing them in keyReleased.

Then it’s a matter of calling keyCodeSet.contains(…) to check if the key has been pressed.


HashSet<Integer> keyCodeSet = new HashSet<Integer>();

public void keyPressed(KeyEvent key) {
    keyCodeSet.add(key.getKeyCode());
}

public void keyReleased(KeyEvent key) {
    keyCodeSet.remove(key.getKeyCode());
}

public boolean isKeyPressed(int key) {
    return keyCodeSet.contains(key);
}

How does this way effect performance, I read somewhere something about Set, that it’s a bit slower ?

That doesn’t work… what it does is the same as keyDown, I want to test is keyPressed, but return true just once !

So you want it to only return true once? You can add change isKeyPressed to:


public boolean isKeyPressed(int key) {
    boolean isPressed = keyCodeSet.contains(key);
    keyCodeSet.remove(key);
    return isPressed;
}

Nope, doesn’t work …

Depends on your operating system. The KeyDown and KeyTyped events are sometimes repeated, sometimes not. Some OSs have a pause before the repeat, others don’t. Just test it and see.

Storing the last key pressed and checking if it is still down should be enough, though.

AFAIK KeyPressed and KeyReleased triggers only once (keyTyped triggers multiply times). But you could have a boolean value check whether the key has been released before it can be used again.

As I said, it depends on how the OS handles the keyboard input.

Best way to find out is to simply add a System.out.println() message to the Key Listener method for each event, and see how it behaves.

In my case, on a WidowsXP machine, the KeyPressed and KeyTyped events keep repeating if I hold the key down.

I managed to do it !!!

here is how:

Made boolean keyUp[keyCode]

if key is pressed, and it’s up set the keyUp to false, and return true.

the Code :

public boolean isKeyPressed(int key) {
		if (keyDown[key]) {
			if (keyUp[key]) {
				keyUp[key] = false;
				return true;
			} else
				return false;
		} else
			return false;
	}

That makes no sense whatsoever. How can a key be down and up at the same time? How do you set these down and up keys?

I don’t see a lot of point in an array of keys that are up. Most keys are up all the time. Makes more sense to simply have a single “keysDown” set and update it on every keyUp and keyDown event.

I think his problem is actually checking when the key changes state, so a single pulse is sent regardless of the key being kept down or up.

If the validation is done against a single flag, the pulse will be sent continually once the flag is set.

Maybe have a hasChanged boolean that is set once the key changes, and reset on the next frame (would need an updateKeys method call each frame)

My earlier post of resetting the key should work too.

It’s like, if the key is down, but was not ( keyUp )…

I tried other things also, this one worked…

It can get a bit confusing sometimes. Good thing is, if it works, you can always refine it in the future.