0

I am trying to make a Snake game, the generic old school one, but I'm having some difficulties using keybinding.

After I make an instance of my Gui class, which makes the JFrame, a JPanel and a JPanel array. After this instance I like to use a while loop to check if the player is still alive and if the player is, the snake moves a square every ~1/4 second depending on the difficulty.

When not in the while loop, I can correctly use the keybinding but when I let my program enter the loop, it doesn't recognize me using my buttons.

Maybe this is a standard thing in Java which I do not know about. If it is, can someone show me how I should approach my problem?

InputMap im = base.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = base.getActionMap();

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "Right");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "Up");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "Down");

am.put("Right", new ArrowAction("Right"));
am.put("Left", new ArrowAction("Left"));
am.put("Up", new ArrowAction("Up"));
am.put("Down", new ArrowAction("Down"));

With the class:

public class ArrowAction extends AbstractAction {
    String txt;

    public ArrowAction(String txt) {
        this.txt = txt;
    }

    public void actionPerformed(ActionEvent e) {
        if (txt.equalsIgnoreCase("Left")) {
            System.out.println("The left arrow was pressed!");
            keyPressed = 0;
        } else if (txt.equalsIgnoreCase("Right")) {
            System.out.println("The right arrow was pressed!");
            keyPressed = 1;
        } else if (txt.equalsIgnoreCase("Up")) {
            System.out.println("The up arrow was pressed!");
            keyPressed = 2;
        } else if (txt.equalsIgnoreCase("Down")) {
            keyPressed = 3;
            System.out.println("The down arrow was pressed!");
        }
    }
}

And just a general while loop:

while (alive == true) {
   // Some stuff happening, not relevant
}

So why is it that my keybindings do not work inside the loop, but do work outside of it?

borisjo
  • 158
  • 1
  • 16
  • 1
    you might need to use a threaded application, one to handle the snake, one to handle the player control that way both run concurrently – David Coler Jan 05 '15 at 22:24
  • 2
    Apparently your event-handling code lives on the same thread as your while loop, so when you do something in the loop then your application can't process new events. – lared Jan 05 '15 at 22:26
  • Your while loop is blocking the event thread, which is a big no-no. Rather than having a separate thread to move the snake, you should subscribe to a periodic timer and update the snake whenever that happens. – jjm Jan 05 '15 at 22:27
  • I'm not used to threads so that is why I tried to keep it simple, but I suppose it is a way better idea to use `Runnable`. – borisjo Jan 05 '15 at 22:44
  • 1
    A complete example is shown [here](http://stackoverflow.com/a/14001011/230513). – trashgod Jan 05 '15 at 22:49

1 Answers1

0

Your problem is in the 'general while loop'. This is not how GUI applications work. In all GUI applications (including Java Swing ones) the framework runs the loop and sends you events to respond to. Everything you write needs to be responding to an event. If it's a background task that should run all the time then it needs to be on its own thread - but I doubt you will need that for your game.

So remove your general while loop and have the 'some stuff' either in its own thread or (much more likely) happening periodically in response to a timer.

sprinter
  • 27,148
  • 6
  • 47
  • 78