Noble Master Games - Public Section

1. Fast Java Flood Fill Algorithm (Java)

Ever been looking for a really fast flood fill algorithm? Here's the solution. The implemented algorithm supports flood fill functionality for common images.

    // Load image to fill.
    Image image = loadImage(...);
    // Create flood fill instance with image. 
    FloodFill floodFill = new FloodFill(image);
    // Do some filling.
    floodFill.fill(100, 100, Color.BLUE);
    ...
    // Get the filled image.
    image = floodFill.getImage();
Flood fill operations are fast and happen directly within the writable raster of an image. The getImage() method does not copy any bytes and returns directly the changed image. The algorithm allows for a fill mask to be used; the image is filled using the borders of the mask. Antialiasing is supported. Pattern-fill has partially been implemented; checkboard only.

Note: There is some redundancy for performance reasons.

Demo: Aevum Obscurum - Multiplayer Strategy Game.
Resource/Download: FloodFill.java

 

2. Isometric Tile Engine with Heightmap (Java)

Please note, some code is partly based on Andrew Davison's book about Java Game Programming. Please refer to the book for information about isometric tile engines and other topics in game design! Also, source code and images supplied will need to be fitted into your game framework of choice. Sources are Java classes related to isometric programming only and will not function without supporting classes such as a game window (some might not compile due to missing references).

The sources employ the MVC code pattern - Model and View classes are seperated. There are two classes in the model. The World and the Terrain as part of the world. To enable slopes for tiles it is necessary to encode the corners for each tile rather than the tile itself. There is always one more column and rows for the array of elevations.

  /** The elevations in meters for the nodes of the tiles (numRows + 1) * (numCols + 1). */
  private short[][] nodeElevations;
The view classes have a supporting class IsoUtil to convert from columns/rows to pixel coordinates.
         |----| isoTileWidth (pixels)
                _    
           /\   |
          /  \  | isoTileHeight (pixels)
          \  /  |
           \/   |
                -


   
               isoWidth (pixels)
             |--------|
   
                  |-> isoX (pixels)
      ------------------------
     |                        | _               _
     |   (row) 0 /\ 0 (col)   | |               |
     |          /  \          | v               |
     | (row) 1 /\  /\ 1 (col) |                 |
     |        /  \/  \        | isoY (pixels)   | isoHeight (pixels)
     |        \  /\  /        |                 |
     |         \/  \/         |                 |
     |          \  /          |                 |
     |           \/           |                 -
     |                        |
      ------------------------
There is a Swing JPanel for rendering. An buffered image is used as back buffer. The WorldIsoPanel handles scrolling and calls the painters and mouse handlers. The WorldIsoPainter draws the heightmap tiles with the TerrainIsoPainter. The sloped tiles are encoded based on the height of each corner of a tile. There currently is only a base height 0 and 1 for each corner which makes 16 tiles. There are 81 tiles for heights 0, 1 and 2. And 256 tiles if there are 4 different height levels for each corner of a tile.

Last but not least there is a mouse handler which handles mouse clicks and movements. WorldMouseHandler calls TerrainMouseHandler which keeps track of mouse position and clicks. Supported are raising as well as flattening of terrain.

To (a) create the world and (b) display the isometric heightmap simply do:
    // set layout
    setLayout(new BorderLayout());

    // add iso panel
    World world = World.createWorld(40, 40);
    long frameTime = 1000000000L / 30;
    int isoTileWidth = 32;
    int isoTileHeight = 16;
    WorldIsoPanel isoPanel = new WorldIsoPanel(world, frameTime, isoTileWidth, isoTileHeight);
    add(isoPanel, BorderLayout.CENTER);

Demo: Isometric Heightmap Demo
Resource/Download: Sources and Images

 

3. Convert an Image to a Byte Array for Inclusion in Source Code (Java)

Java allows image objects to be converted to a byte array for transmission over a network or storage in a database. A byte array can be converted back into an image object in a platform independent manner. The byte array can be compressed for optimal size.

Going one step further: a byte array can be converted for inclusion in a Java source file offering the following benefits:

Please note there is some overhead to store an image in Java source code. The size of the image roughly doubles when stored in the code, thus making the procedure less feasible for big images.

The following code converts an image to a byte array using our ImageUtil.java class and outputs it as Java code for inclusion in a .java source file.
    // Load image
    Image image = loadImage(...);
    
    // Convert the image to a byte array
    byte[] data = ImageUtil.imageToByteArray(image);
    
    // Output data
    FileOutputStream fos = new FileOutputStream(args[1], false);
    DataOutputStream dos = new DataOutputStream(fos);
    for (int i = 0; i < data.length; i++) {
      if ((i % 8) == 0) {
        dos.writeBytes("\n");
      }
      dos.writeBytes("(byte)0x");
      String hex = Integer.toHexString(data[i]);
      if (hex.length() == 1) {
        hex = "0" + hex;
      }
      else if (hex.length() > 2) {
        hex = hex.substring(hex.length() - 2);
      }
      dos.writeBytes(hex);
      dos.writeBytes(", ");
    }
    dos.flush();
    dos.close(); 
    fos.flush();
    fos.close();

Example Conversion: Image: / Java Source Code: Byte Array
Resource/Download: ImageUtil.java

 

Appendix A: Open Source Projects

Disease Simulation Framework: DiSiF
Eye Tracking Data Recording & Analysis: EventStream

 

Appendix B: Resource

Code courtesy by: Noble Master Games
Contact: Christoph Aschwanden