0

I want to include a KeyHandler for my snake game, made with JavaFX.

Main.java

public class App extends Application {

private static final int WIDTH = 450;
private static final int HEIGHT = 450;

private GameLoop loop;
private Grid grid;
private GraphicsContext context;

@Override
public void start(Stage primaryStage) throws Exception {
    StackPane root = new StackPane();
    Canvas canvas = new Canvas(WIDTH, HEIGHT);
    context = canvas.getGraphicsContext2D();

    canvas.setFocusTraversable(true);
    canvas.setOnKeyPressed(new KeyHandler());;

    reset();

    root.getChildren().add(canvas);

    Scene scene = new Scene(root);
    primaryStage.setResizable(false);
    primaryStage.setTitle("Snake");
    primaryStage.setOnCloseRequest(e -> System.exit(0));
    primaryStage.setScene(scene);
    primaryStage.show();

    (new Thread(loop)).start();
}

private void reset() {
    grid = new Grid(WIDTH, HEIGHT);
    loop = new GameLoop(grid, context);
    Painter.paint(grid, context);
}

public static void main(String[] args) {
    launch(args);
}

}

I want to use the method "canvas.setOnKeyPressed(new KeyHandler());" to setup the different keys to move the snake like this:

Keyhandler.java

public class KeyHandler implements EventHandler<KeyEvent> {
    private GameLoop loop;
    private Grid grid;

@Override
public void handle(KeyEvent event) {
    Snake snake = grid.getSnake();
    if (loop.isKeyPressed()) {
        return;
    }
    switch (event.getCode()) {
    case W:
        snake.setUp();
        break;
    case DOWN:
        snake.setDown();
        break;
    case LEFT:
        snake.setLeft();
        break;
    case RIGHT:
        snake.setRight();
        break;
//      case ENTER:
//          if (loop.isPaused()) {
//              reset();
//              (new Thread(loop)).start();
//          }
        }
    };

}

When I start the application, every time I am pressing a key I am getting nullPointer exceptions.

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at snake.controller.KeyHandler.handle(KeyHandler.java:15)
    at snake.controller.KeyHandler.handle(KeyHandler.java:1)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$KeyHandler.process(Scene.java:4058)
    at javafx.scene.Scene$KeyHandler.access$1500(Scene.java:4004)
    at javafx.scene.Scene.processKeyEvent(Scene.java:2121)
    at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2595)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:217)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:149)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$1(GlassViewEventHandler.java:248)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:390)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:247)
    at com.sun.glass.ui.View.handleKeyEvent(View.java:547)
    at com.sun.glass.ui.View.notifyKey(View.java:971)
Cenasa
  • 531
  • 9
  • 27
  • 3
    `setOnKeyPressed(new KeyHandler(snake));` ?? For more help post [mcve] including the fxml where canvas is defined. – c0der Apr 11 '19 at 11:18
  • Canvas is defined by JavaFX. Snake is another Class with methods. I want to use the snake I've created in the controller class. – Cenasa Apr 11 '19 at 11:30
  • 1
    Tip: if you want to address a user in comment add his name to it: for example @c0der. Also [edit] to add any significant information. "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example." – c0der Apr 11 '19 at 11:41
  • @c0der : thanks for your tips. I tried to make it more clearer, but I feel like it still is not clear enough. I just dont really know what I could explain clearer. – Cenasa Apr 11 '19 at 12:05
  • 1
    read the help page referenced by @c0der and provide the example as suggested ;) – kleopatra Apr 11 '19 at 12:14
  • I would first try to do it without using KeyHandler as a separate class. – SedJ601 Apr 11 '19 at 13:07
  • Looks like your `GameLoop` object is never initialized, same with the `Grid` object. Hence the `NPE`. Initiate those by doing something like @c0der suggested in the first comment. – Hypnic Jerk Apr 11 '19 at 14:23
  • There are no assignments to the `grid` or `loop` fields of your `KeyHandler` in the code you posted. – fabian Apr 11 '19 at 17:43

0 Answers0