Keyboard Controlled Menu (Speed is too fast)

I am creating a main menu for a 2D game where the player can select one of four different game options using the WASD keys (actually only W and S; up and down). However, the menu’s update method runs about 60 times per second, so pressing the down key for a short period of time will cause the selector to quickly go to the bottom of the list and skip the two middle options (because the method runs about 20 times during a short keypress). Below is the source code for the update method found in the Menu class. I would like to have two keyboard objects (the current keyboard and previous keyboard) so that if the previous keyboard did not detect the key press but the current keyboard did, the update method will know that this was the first time in a while that the key was pressed. At the end of the method, the current keyboard becomes the previous keyboard for the next update. A fix to my current method is appreciated, as well as any other possible ways to handle this problem.

private int selected = 0;

public void update() {
int move = 0;

	if(!previousKeyboard.getUp() && keyboard.getUp()) move--;
	else if(!previousKeyboard.getDown() && keyboard.getDown()) move++;
	int nextSelected = selected + move;
	if(nextSelected >= 0 && nextSelected < OPTIONS.length) selected = nextSelected;
	
	if(!previousKeyboard.getEnter() && keyboard.getEnter()) { // If selected
		switch(selected) {
		case 0: // Singleplayer
			game.setMenu(null); // Remove menu
			game.setGameMode(1);
			break;
		case 1: // Multiplayer
			game.setMenu(null); // Remove menu
			game.setGameMode(2);
			break;
		case 2: // High Scores
			game.setMenu(new HighScoresMenu());
			break;
		case 3: // About
			game.setMenu(new AboutMenu());
			break;
		}
	}
	
	previousKeyboard = keyboard;

}

You need to detect if a single key input has been pressed, tapped, and check its last key input state. That’s 3 things you need to check for.

For example, if I need to detect an “UP” key press, I would do this:


//Mock game loop.
while (true){
     //...60 FPS

     //Somewhere in the beginning, all key inputs have its states cleared.
     UP.setKeyState(false);
     UP.setLastKeyState(UP.getKeyState());

     // --------------------------------------

     //User pressed the UP key...
     UP.setKeyState(true);

     // --------------------------------------

    //Detecting up key....
    if (UP.isPressed() && !UP.getLastKeyState()){
          UP.setLastKeyState(true);
          //Do something here...
    }
}

My own implementation:

InputHandler:
https://github.com/tommai78101/PokemonWalking/blob/master/src/main/InputHandler.java

Keys:
https://github.com/tommai78101/PokemonWalking/blob/master/src/main/Keys.java

Thanks for the help. It didn’t take long to fix the problem!