Fly - Tutorial

Home >> Tutorial

This section is created to help anyone who want to getting understand Fly Game Engine. it is simple to follow, and hopefully in this quick five steps, you will master the basic capability to write game with Fly.

  1. Prerequisite
  2. Starting the FLY library
  3. Understanding Game class & Accessing core objects
  4. Implementing interface Level
  5. Understanding Sprite and Checking Collision
  6. Using fly.ext library

a. Prerequisite

To be able to follow tutorial below, you have to know basic java programming. New to java? Don't worry, you can learn it at

b. Starting the FLY library

To utilise this library is very simple. Activate Game class and follows by calling init(widht x height, fullscreen).

    public static void main(String args[]) {
        fly.core.Game g = new fly.core.Game();

c. Understanding Game class & Accessing core objects

Game class is the main object and it has access to other core objects. Once the object is activated, the supporting functions should be called in correct sequence, as follows:

    init(width, height, fullscreen)This is to begin with, and tells the system to initialise variables and system objects.
    start(Level)This function should be called whenever the game is started, or go to next level, or restart current level
    dispose()It should be called after the application has finished running to release locked memory by the system

Because Game class has access to core objects (standard inputs, outputs, and caching), developer must use Game class to gain access to other core objects. Following are the list:

getKeyboard()Return keyboard object, a class responsible for handling keyboard events such as getting key press, and key down

Related: All key constants is listed onjava.awt.KeyEvent

getMouse()Return mouse object, a class responsible for handling mouse events such as getting mouse coordinate, or mouse click

Related: All mouse constants is listed onjava.awt.MouseEvent

getDisplay()Return display object, a class responsible for handling screen display , such as changing screen resolution, or getting active screen dimension
getCache()Return cache object, a class responsible for caching various resources to speed up game performance. See cache section for detail information

Below is an example to get keyboard object, and then find out whether key F1 is pressed.

    if (fly.core.Game.getKeyboard().getKeyUp()==java.awt.KeyEvent.VK_F1) {
        System.out.println("F1 is pressed);

d. Implementing interface Level

Interface Level act as main coordinator between game objects, input/output, and logics. It is consisted of four functions, which will be automatically called by Game class depending on the condition.

    init()This function is called once, when Level is started by calling Game.start(Level). Developer should override it to perform required variables and objects initialisation such as generating sprites
    paint(graphics)This function is called whenever system need refresh the screen. Normally it would be called more than once in a second. The function sends a parameter called as graphics which acts as painter. Developer should override it to tell the painter which sprites and backgrounds are to be drawn
    update(elapsed)This function is called whenever system is updated, similar with paint(graphics) it will be called more than once in a second. elapsed parameter contains lapsed time since it was called previously. Developer should override it to write main game logics, such as sprites activation, or getting keyboard input.
    dispose()This function is called once, when Level is no longer in used. Basically when Game.start(Level) is recalled or Game.stop() is called. Developer should override it to write release system pointers and releasing unnecessary memory used.
    function to be called by system repetitively to check current Level status. As when it is still active, Game.start(Level) is continuously looping, performing updating logics, and repainting screen.
Below is a simple example implementing Interface Level.

    public class L1 implements fly.core.Level {
        fly.core.Keyboard key;
        fly.ext.Sprite sprite1;
        public void init() {
            sprite1 = new fly.ext.Sprite();
        public void paint(java.awt.Graphics2D g) {
        public void update(long elapsed) {
            if (key.isKeyDown(java.awt.KeyEvent.VK_RIGHT) {
                sprite1.setCoordinateX(sprite1.getCoordinateX() + 1);
            if (key.isKeyDown(java.awt.KeyEvent.VK_LEFT) {
                sprite1.setCoordinateX(sprite1.getCoordinateX() - 1);
        public void dispose() {
            sprite1 = null;
            key = null;
        public boolean isActive() {
            return true;

Source above would create a sprite and move it to left or right direction depending on key pressed. To see L1 in action, activate the Game class, and call start(L1);

    public static void main(String args[]) {
        Game g = new Game();
        g.start(new L1());

e. Understanding Sprite and Checking Collision

Sprite is a class contains small graphic (changeable) that can be moved independently around the screen. Below are some of most frequently used functions:

    setImage(location)Call this function to set or change image to be displayed
    paint(Graphics)Call this function to draw the sprite into the screen. It need to be called from Level.paint(Graphics)


    Call this function to change coordinate of the sprite
    update(elapsed)To be implemented when developer extend Sprite class. This would be a place to control sprite’s logics such as movement speed, or animation logics
    checkCollision(second sprite,enable pixel collision method)Call this function to check whether the sprite is collided with another sprite. Pixel collision is a precise method of collision checking by comparing pixel-to-pixel between images.
    checkCollision(coordinate)Call this function to check whether specified coordinate is inside the sprite area. (e.g. to check whether a mouse is pointing to a particular sprite)
The reason that sprite is explained in separate section because most of the time, it needs to be inherited to leverage it functionalities, such as adding energy, controlling movement speed, or animation logics. Example below illustrates how to make sprite’s image changes every one second.

    public class Foo extends fly.ext.Sprite {
        long ttlElapsedTime;

        public void update(long elapsedTime) {
            ttlElapsedTime += elapsedTime;
            if (ttlElapsedTime>=1000) {
                if (getImage()=="foo1.png") setImage("foo2.png");
                    else setImage("foo1.png");
            } // end if

Second reason, is because checking collision is to be done in sprite class. See the example below to find out how easy managing collision with Fly. Please take note that pixel-collision checking requires more times to process, and it may affect overall performance. However, there’s option the enable/disable the pixel-collision method.

    // initialising two sprites with different image and coordinate
    public static init(fly.ext.Sprite sprite1, fly.ext.Sprite sprite2) {
        sprite1 = new fly.ext.Sprite();
        sprite2 = new fly.ext.Sprite();

    public static void main(String args[]) {
        fly.ext.Sprite sprite1, sprite2;
        init(sprite1, sprite2);
        //checking collision
        System.out.println(sprite1.checkCollision(sprite2, true));

f. Understanding Cache

Reading data from file does slow down overall performance. Because of that, it needs a cache to store resources into memory. By default caching process is automatically handle by system, however in some occasion it may need to do it manually. E.g. a file contains collection of sprite’s images, it need to be split and cached separately, later a sprite class will recall it from memory.

    public class L2 implements fly.core.Level {
        public void init() {
            java.awt.BufferedImage img[];
            fly.core.Cache cache = fly.core.Game.getCache();
            // split image in sprites.png four images (2x2)
            img = fly.ext.Util2D.splitImage("sprites.png",2,2);
            // cache images, set the key as img[number]
            for (int i=0; i<img.length; i++) cache.cacheImage("img"+i,img[i]);
            // create a sprite
            sprite1 = new fly.ext.Sprite();
            // set an img from cached images
        public void paint(java.awt.Graphics2D g) { }
        public void update(long elapsed) { }
        public void dispose() { }
        public boolean isActive() { return true; }

Note that getImage(source)function work as: it will look needed resource from cache, if it is cannot be found, then getImage() will read from disk, and cache it. So next time the resource is used, it will be read from cache. This caching technique is also applicable for other objects such as sound, music, and text

g. Using fly.ext library

Library fly.ext contains extended objects to leverage game experience. Below is the list:

    SpriteClass to reproduce sprite. See sprite section for detail information
    SoundClass to reproduce sound effect
    MusicClass to reproduce background music (MIDI)
    TextClass to reproduce text manipulation, such as installing a font and drawing paragraph into the screen
    Util2DUtilities class contains image manipulation, such as splitting image, and creating semi transparent colour.

    Collection methods encapsulated in a static class

To utilise these classes are quite simple, just need to activate the class, and execute desired method. Example below illustrate how to play a sound, and background music

    public class L3 implements fly.core.Level {
        public void init() { }
        public void paint(java.awt.Graphics2D g) { }
        public void update(long elapsed) {
            // press 1 to play sound or 2 to play a midi
            if (fly.core.Game.getKeyboard().getKeyUp()==java.awt.KeyEvent.VK_1) {
                new fly.ext.Sound("sound1.wav").play();
            if (fly.core.Game.getKeyboard().getKeyUp()==java.awt.KeyEvent.VK_1) {
                new fly.ext.Music("music1.mid").play();
        public void dispose() { }
        public boolean isActive() { return true; }

Good luck. And enjoy!