KeyListener, Multiplayer input

Hi again :wink:

I wrote a little game where up to 4 players can
drive a little car and play against the other players.
You can use four keys to steer the car and two
keys to shoot some nasty little bullets (from a pneumatic stapler for example).
It works really well with different maps and special effects and runs
with up to 60 fps with Fullscreenmode.

The big problem is that sometimes the keyevents don’t do what they should do.
The game should be played on one keyboard and even with only two players
errors already occur.
Sometimes when I realease the firekey, it keeps on firing
or I can’t steer left or the other player is accelerating although he released the key.

Here’s the code:


public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();
		if(active){
			int i = 0;
			for(int[] q : SnS.keys){
				int i2 = 0;
				for(int q2 : q){
					if(q2 == key){
						keyDown[i][i2] = true;
					}
					i2++;
				}
				i++;
			}
		}	
	}

	public void keyReleased(KeyEvent e) {
		int key = e.getKeyCode();
		if(active){
			int i = 0;
			for(int[] q : SnS.keys){
				int i2 = 0;
				for(int q2 : q){
					if(q2 == key){
						keyDown[i][i2] = false;
						if(i2 == 0 || i2 == 1){//release steeringwheel
							smoothSteering[pl[i].plIndex] = 0;
						}
					}
					i2++;
				}
				i++;
			}
		}			
	}


public static int maxSmooth = 10;
	public void move(){
		int i = 0;
		for(Player p : pl){
			if(p.alive){
				if(p.canMoveCar()){
					if(keyDown[i][0]){
						if(smoothSteering[p.plIndex] < 0){
							smoothSteering[p.plIndex] = 0;
						}else{
							smoothSteering[p.plIndex]++;
							smoothSteering[p.plIndex] = Math.min(smoothSteering[p.plIndex],maxSmooth);
						}
						p.angle += p.getMoveAngle(Math.abs(smoothSteering[p.plIndex]));
					}
					if(keyDown[i][1]){
						if(smoothSteering[p.plIndex] > 0){
							smoothSteering[p.plIndex] = 0;
						}else{
							smoothSteering[p.plIndex]--;
							smoothSteering[p.plIndex] = Math.max(smoothSteering[p.plIndex],-1*maxSmooth);
						}
						p.angle -= p.getMoveAngle(Math.abs(smoothSteering[p.plIndex]));				
					}
					if(keyDown[i][2]){
						p.changeSpeed(-1);
					}
					if(keyDown[i][3]){
						p.changeSpeed(+1);				
					}					
				}
				if(keyDown[i][4]){
					p.tryShot(p.angle);
				}
				if(keyDown[i][5]){
					p.tryBackShot();
				}
				p.angle = p.angle%360;
				move(p);
				i++;
				p.update();
			}
		}
		checkMapForCollisions();
		checkMapForWallCrash();
		resetCrashedPlayer();
	}

If you don’t understand any of the code, please ask.
The smoothSteering is just so that the player has better
control of small angles.
int[][] keys contains the KeyEvent_VK… keycodes where the first dimension is for the 4 players
and the second dimension is for the 6 keys: up, down, left, right, shot, backshot.
boolean[][] keyDown is the same for the dimensions and just stores if a key is held down or not.

I played the red baron (http://marcin-kochanowski.com/RedBaron4K.html)
which was programmed for the java4k contest in 2009
with a friend for hours and it works well with many keys pressed at the same
time. (Up to 9 keys, when 3 people are playing)
Unfortunately the programmer didn’t release the code, so
I couldn’t learn from it…
If you read this: please help me :wink:

Doesn’t anyone know
why java cannot handle multiple keys pressed at the same time ?
Or is my approach wrong ?

As it looks, there seem to be some keyReleased and keyPressed events
which aren’t processed…
Otherwise the boolean values would’t remain in their state.

I just read something about the problem with multiple keys
pressed at the same time.
I have WinXP and my keyboard was connected with the pc by PS2.
I read that USB doesn’t have this problem (with 3 or more keys pressed
also a noisy beep appears).
So I changed the connection from PS2 to USB…
I hope it helps, couldn’t try so far…

Well,
I made some tests
and here’s the result:
When too many keys are held down,
some of them aren’t recognized by java.
Also it seems to depend a little on which keys are pressed.

For example the first player
steers to the right while accelerating and
firing some bullets and the second player
steers right but can’t fire,
because pressing the fire-key doesn’t have any effect.

(I had WASD for player one and the cursorkeys for player two for moving
and B / NUM_0 for firing with player one / two)

:’(

I hate this, the game would be lots of fun
but instead it’s straining my nerves even before playing.

Would it work with slick ?

This isn’t a problem with java, it’s a limitation of the keyboard hardware.

Awesome !!!
Your link was really helpful, I understand the actual problem now.
Now it should be possible to change my keyboardsettings
in order to fit every players movement.
I will post it here, when the game works with 2 or maybe 3 players.
Maybe anyone else with a similar game can use
the layout I choose for the movement.

Thank you a lot :slight_smile:

P.S.
You may think: “Who in the world is playing a game with two people on one keyboard nowadays?”
Actually it is quite fun to play such games in a little tournament with a friend once in a while.
Red Baron in J4k is one of our favorite games in the tournament,
it is written for one keyboard as well :wink:

Just do this:

in keyPressed:
Add the keycode to an ArrayList.

in keyReleased:
Remove that keycode from the ArrayList.

Every game loop update:
Perform actions based on all the keycodes in the ArrayList.

Open a text entry window of some kind.
Press down (and hold down) the ‘E’ key.
Without letting go, press down (and hold down) the ‘C’ key.
Now tap repeatedly on the ‘U’ key. Do you see any u’s coming out on the screen? No? I didn’t think so.

Completely unable to reproduce this problem… It’s strange

Oh oups, on my keyboard it bug at 7 keys. So no more than 6 key down at a time for me :frowning:
And on my laptop F, G, and H produce a problem but not on my desktop. So I guess that all keyboard are not the same…

You may be able to work around it for your keyboard, but you can be sure other keyboards will behave differently. There are even specialized keyboards that do not have this problem, Google “steelkeys” or “keyboard ghosting”. I believe all keyboards will support two keys at once, after that sometimes it will work, sometimes it won’t. Of course, the ctrl, alt, and shift modifier keys are separate from this problem.

It’s working now.
I managed to choose the right keys.
That’s also possible because a player won’t need
to press the steer-left-key and the steer-right-key at the same time.
On other keyboards it may fail again, but
I think most keyboards are the same concerning at least the letters (I don’t use ‘Z’ or ‘Y’).
When the problem appears on another keyboard one can
change the keysettings ingame (This isn’t the nicest way but it works).

If anyone wants to know:
I chose W,A,S,D for moving the first player and NUM_5,NUM_1,NUM_2,NUM_3 for the second one.
F and G are for firing bullets with the first player and for the second one it’s NUM_+ and NUM_Enter.
I’m trying to find the right keys for the 3rd player now, but the game will
mostly be played by just two players.