I'm trying to implement a traditional game loop using JavaFX's AnimationTimer:

@Override
public void handle(long currentNanoTime) {
    // calculate time since last update.
    double elapsedTime = (currentNanoTime - lastNanoTime) / 1e9f;
    lastNanoTime = currentNanoTime;

    // Handle Input
    switch (currentScreen) {
           case AREA_ONE-> areaOneInputHandler.handle();
           case AREA_TWO-> areaTwoInputHandler.handle();
    }

    // Update the models
    areaOneUpdater.update(elapsedTime);
    areaTwoUpdater.update(elapsedTime);

    // Clear the canvas 
    gc.clearRect(0,0,InterfaceConstants.CANVAS_WIDTH,
    InterfaceConstants.CANVAS_HEIGHT);

    // Render
    switch (currentScreen) {
    case AREA_ONE -> areaOneRenderer.render();
    case AREA_TWO-> areaTwoRenderer.render();
    }
}

What I'm trying to figure out is the best way to implement the handle() methods because the 'input' in this case is mouse/keyboard events triggered on the canvas node. The current idea I have is:

  • Attach event listeners where the canvas is initialized
  • Store those mouse/keyboard event objects in a GeneralHandler class.
  • Let areaOneInputHandler etc have a reference to this general handler class and the appropriate model (areaOneModel).
  • handle() then updates the model.

One question is if it's correct for handle() to update the model, or whether that should be entirely done with update(). Is it okay to have the model updated in both?

A basic implementation of what I talked about would be:

GeneralHandler.java

public class GeneralHandler {

    private MouseEvent clickMouseEvent;

    // Getters and Setters omitted
}

Where canvas is initialized:

canvas.setOnMouseClicked(generalHandler::setClickMouseEvent);

AreaOneInputHandler.java

public class AreaOneInputHandler extends Handler {

    private AreaOneModel areaOneModel;
    private GeneralHandler generalHandler;

    public AreaOneInputHandler (AreaOneModel areaOneModel, GeneralHandler generalHandler) {
        this.areaOneModel= areaOneModel;
        this.generalHandler = generalHandler;
    }

    @Override
    public void handle() {
        if (generalHandler.getClickMouseEvent() != null) {
           // Update the model
            generalHandler.setClickMouseEvent(null);
        }
    }
}

Is this appropriate? This is my first real attempt at implementing a game loop and I am wondering if this is breaking any norms or will cause me problems further down the line.

0 Answers