Problem reading keys

Just noticed a problem in my code, when I use the same key to take input from two menus, it will re-use the input again for the next one.

Example: In my program, pressing enter opens instructions, but in the instructions page, enter goes back to the menu. Result is that it appears as if the instructions aren’t coming up at all.

I am using a different key listener for the main menu and for the instructions screen, and I remove it when I switch to the other.

Here’s the relevant code -

public void keyPressed(KeyEvent e)
		{

			if (mainMenu)
			{
				key = e.getKeyCode();
				if (key == KeyEvent.VK_UP)
				{
					if (playIsSelected)
					{
						playIsSelected = false;
						quitIsSelected = true;
					}
					else if (insIsSelected)
					{
						insIsSelected = false;
						playIsSelected = true;
					}
					else if (quitIsSelected)
					{
						quitIsSelected = false;
						insIsSelected = true;
					}
				}
				
				if (key == KeyEvent.VK_DOWN)
				{
					if (playIsSelected)
					{
						playIsSelected = false;
						insIsSelected = true;
					}
					else if (insIsSelected)
					{
						insIsSelected = false;
						quitIsSelected = true;
					}
					else if (quitIsSelected)
					{
						quitIsSelected = false;
						playIsSelected = true;
					}
				}
				
				if (key == KeyEvent.VK_ENTER)
				{
					if (playIsSelected) gameInit();
					if (insIsSelected) instructionsInit();
					if (quitIsSelected) System.exit(0);
				}
			}
			
			if (playing)
			{
				p.keyPressed(e);
			}
			
			if (instructions)
			{
				key = e.getKeyCode();
				if (key == KeyEvent.VK_ENTER) menuInit();
			}
		}

Thanks,
-Nathan

I don’t see how keyPressed could be called twice, maybe you have put this ActionListener twice on the same component. More information will probably be helpful.

Here’s the source - http://www.mediafire.com/?d1sxprd5xf52s1w

p.s. Just ignore the Render class. The REAL render method is in the Main class.

Well your big mistakes is squeezing all the logic into 1 file that even I got completely confused how it runs.

Separate all the screens out into separate files. Make a Screen interface that has an update, render, keyPressed, and keyReleased methods and each class, MainMenu, Instructions, Game, implement it. Then you have 1 listener that forwards those events to the current screen.

Just some ideas to get you going :wink:

Except you’re doing java4k :smiley:

In my last approach, I let the main class to listen and tell current screen about keys. So in my interface class there is method for this.

I don’t understand how an interface would simplify this. I haven’t really used them before. Could you post some example code of what a basic version of this might look like?


public interface Screen {
    public void update();
    public void render(Graphics2D g);
    public void keyPressed(int keyCode);
    public void keyReleased(int keyCode);
}

And then you game states would implement it:


public class MainMenu implements Screen {
    private Game parent;
    
    public MainMenu(Game game) {
        parent = game;
    }
    
    public void update() {
        ...
    }

    public void render(Graphics2D g) {
        ...
    }

    public void keyPressed(int keyCode) {
        if(keyCode == KeyEvent.VK_ENTER)
            parent.setScreen(new Instructions());
    }
    
    public void keyReleased(int keyCode) {
        ...
    }
}

Thanks. I don’t quite understand how the rendering would work when the rendering is being done in multiple different methods, though.

The rendering is all done by the Graphics2D object so all you need to do is pass it around.

If you were doing it the way we talked about in another post of yours, with a boolean value like keyEnter: You can make it a non-repeating key. In the part of the program where you check to see if keyEnter is true (set by keyPressed and keyReleased), if it is true then immediately set it to false and carry on, then the next time you check to see if it is true it won’t be unless you have released and pressed it again.

… Also I wouldn’t use multiple key listeners. Just have one that sets the boolean variable representing that key and use your main/menu loops to work with them.

Could you post the instructionsInit() method and the Instruction screen code?