Java FX – GUIs
TOPIC 07 – GAME LOOP OR ANIMATION

 

 

LESSON NOTE

 

 

GAME LOOP OR ANIMATION

 

Both a game or animation require for a program to update and redraw regularly.  This can be done using the AnimationTimer class.  Once started, such a timer automatically calls its handle method at 60 frames per second.  It is in the handle method that we make update and redraw the game/animation.

 

NOT SO FAST

 

There is one complication.  AnimationTimer is not an interface.  So we can't simply implement it like we did for EventHandlers.

 

AnimationTimer is an abstract class.  That is simply a class that you must extend in order to use.  When extending, you are required to implement the handle method. 


OPTION 1 – EXTEND ANIMATIONTIMER

 

There are two ways to work with this.  One is to extend the AnimationTimer class and then use our new class.  This does lead to having two files to deal with – but that's not a very big deal.

 

OPTION 2 – USE AN ANOMYMOUS INNER CLASS

 

Java also allows us to implement the required handle method for this abstract class inside another class.  It's a little ugly to look at but it does keep the core of our application in a single file.

 

EXAMPLE OF OPTION 1

 

In this example, we will simply have an update() method that will be called every frame.  To keep things simple, we will just output to console for now.

Every frame, the handle method in the second file is called.  It in turn calls the update method inside the first file. 

 

import javafx.application.Application;

import javafx.event.EventHandler;

import javafx.scene.Group;

import javafx.scene.Scene;

import javafx.scene.canvas.Canvas;

import javafx.scene.canvas.GraphicsContext;

import javafx.scene.input.MouseEvent;

import javafx.scene.paint.Color;

import javafx.scene.shape.ArcType;

import javafx.stage.Stage;

 

public class AnimationTimerApp extends Application

{

     public MyAnimationTimer mat;

     public GraphicsContext gc;

 

     public AnimationTimerApp()

     {

        mat = new MyAnimationTimer(this);

    }

    

    public void start(Stage primaryStage)

    {

        primaryStage.setTitle("Animation or Game Loop");

        Group root = new Group();

        Canvas canvas = new Canvas(400, 400);

        gc = canvas.getGraphicsContext2D();       

        root.getChildren().add(canvas);

        Scene scene = new Scene(root);           

        primaryStage.setScene(scene);

        primaryStage.show();

        mat.start();   //start timer here

    }

    

     public void update()

     {

          System.out.println("Updating");

         

          //Here we would update locations for everything.

          //Then we would redraw everything.

     }

    

    public static void main(String[] args)

    {

        launch(args);

    }

}

import javafx.animation.AnimationTimer;

 

public class MyAnimationTimer extends AnimationTimer

{

     public AnimationTimerApp ata;

    

     public MyAnimationTimer(AnimationTimerApp ata)

     {

          this.ata = ata;

     }

    

     public void handle(long currNanoTime)

     {

          ata.update();

     }

}