Aegidius
 Plüss   Aplulogo
     
 www.aplu.ch      Print Text 
© 2021, V10.4
 
  JGameGrid
 
 

The source code of all examples is included in the JGameGrid distribution.

 

A Progress Bar Indicator

It is common to inform the user about the current state of a long running action by displaying a bar that increases in length. Most GUI control libraries contain a widget called "progress bar"; in the Java Swing framework the progress bar widget is implemented in the class JProgressBar. Simple JGameGrid based applications often use the GameGrid frame as container where controls like buttons are implemented as subclasses of the class Actor. Because sprites (actor images) may be created dynamically using the GGBitmap class that provides the common Java2D graphics methods, it is rather straightforward to generate programmatically a non-filled rectangle that contains a filled rectangle with changing size. To simplify your work, the GGProgressBar library class does the job for you.

In the next example we simulate slowly loading sprite images. For demonstration purposes we slow down the loading process artificially by adding a delay() in the loading loop. The GGProgressBar constructor takes parameters to choose the basic properties: the GameGrid reference where the actor is displayed, the location and the size. An extra boolean parameter can be used to determine, if the bar is horizontal or vertical. There are a couple of methods to set special properties (minimum and maximum value, color, text, etc.). setValue(double value) adds the bar to the game grid and performs a GameGrid.refresh() to show it on top of all other actors.

import ch.aplu.jgamegrid.*;
import java.awt.*;

public class Ex25 extends GameGrid
{
  public Ex25()
  { 
    super(101060Color.red, false);
    getBg().clear(Color.white);
    show();
   
    int value = 0;
    int index = 0;

    GGTextField tf = 
      new GGTextField(this"Loading actors now..."new Location(79)true);
   tf.setLocationOffset(new Point(-50-20));
   tf.show();
    
    GGProgressBar bar = new GGProgressBar(thisnew Location(79)20020);
    bar.setUnit("%");
    while (value <= 100)
    {
      bar.setValue(value);
      value += 1;
      if (value % 10 == 0)
      {
        Actor a = new Actor("sprites/car" + index + ".gif");
        addActor(a, new Location(1, index));
        index++;
      }  
      delay(50);
    }
    tf.setText("All done");
  }  
 
  public static void main(String args[])
  {
    new Ex25();
  }
}

Execute the program locally using WebStart.

 

jgamegridex25

 

 

Coloring Using Flood Fill

With most painting tools you can fill a bounded unicolored region using the watering can tool floodfill . The algorithm used to change the color of each pixel in a bounded region is called "flood fill algorithm" (see Wikipedia http://en.wikipedia.org/wiki/Flood_fill). It's highly recursive and JGameGrid is an ideal tool to demonstrate the algorithm in a simple 10x10 grid. As stated in the Wiki reference, the recursive method floodFill() takes three parameters: The current cell, the old color and the new color. The algorithm is quite easy to understand and shows the practical use of recursive algorithms (some people tells you the contrary):

Pseudocode:

floodFill(cell, oldColor, newColor):
1. If the color of cell is not equal to oldColor, return.
2. Set the color of cell to newColor.
3. Perform floodFill(one step to the east of cell, oldColor, newColor).
   Perform floodFill(one step to the south of cell, oldColor, newColor).
   Perform floodFill(one step to the west of cell, oldColor, newColor).
   Perform floodFill(one step to the north of cell, oldColor, newColor).
4. Return

In Java:

import ch.aplu.jgamegrid.*;
import java.awt.Color;
import ch.aplu.util.Monitor;

public class Ex26 extends GameGrid
  implements GGMouseListener
{
  private final Color borderColor = Color.red;
  private final Color oldColor = Color.black;
  private final Color newColor = Color.green;
  private Location startLocation;
  private GGBackground bg;

  public Ex26()
  {
    super(101060Color.darkGray, false);
    setTitle("Drag to create a closed region. Click inside to fill.");
    bg = getBg();
    addMouseListener(this, GGMouse.lDrag | GGMouse.lClick);
    show();
    Monitor.putSleep();
    floodFill(startLocation, oldColor, newColor);
  }

  private void floodFill(Location cell, Color oldColor, Color newColor)
  {
    if (!bg.getColor(cell).equals(oldColor))
      return;
    bg.fillCell(cell, newColor);
    refresh();
    delay(300);
    for (int i = 0; i < 4; i++)
    {
      Location loc = cell.getNeighbourLocation(* 90);
      if (isInGrid(loc))
        floodFill(loc, oldColor, newColor);
    }
  }

  public boolean mouseEvent(GGMouse mouse)
  {
    Location loc = toLocationInGrid(mouse.getX(), mouse.getY());
    switch (mouse.getEvent())
    {
      case GGMouse.lDrag:
        bg.fillCell(loc, borderColor);
        refresh();
        break;

      case GGMouse.lClick:
        startLocation = loc;
        setMouseEnabled(false);
        Monitor.wakeUp();
        break;
    }
    return true;
  }

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

Execute the program locally using WebStart.

 

floodfill

 

The flood fill algorithms has been implemented on a pixel basis in the GGBitmap class. The method is useful if you want to colorize actors on-the-fly at runtime. The "seed" image must have a bounded unicolored region and all parts to be colorized have to be connected. The background is transparent. We prepared the image of a camel seed with a white inner region. In the following example camels are created with random colors whenever you you click the window. The caravan moves to the right and camels are removed from the game grid when they are outside the visible window in order to save memory space.

import ch.aplu.jgamegrid.*;
import
 java.awt.image.BufferedImage;
import
 java.awt.*;

public
 class Ex27 extends GameGrid implements GGMouseListener
{
  
private BufferedImage seed;

  
public Ex27()
  
{
    
super(600, 400, 1, false);
    
setSimulationPeriod(30);
    
setTitle("Click to generate a colored camel");
    
getBg().clear(new Color(250, 245, 202));
    
addMouseListener(this, GGMouse.lPress);
    
show();
    seed 
= new Actor("sprites/camel.gif").getImage();
    
doRun();
  
}

  
public boolean mouseEvent(GGMouse mouse)
  
{
    
int r = (int)(128 * Math.random() + 128);
    
int g = (int)(128 * Math.random() + 128);
    
int b = (int)(128 * Math.random() + 128);
    
Color color = new Color(r, g, b);

    Location location 
= toLocation(mouse.getX(), mouse.getY());
    Actor a 
= new Actor(GGBitmap.floodFill(seed, new Point(75, 30),
      
Color.white,
      color
));
    
addActor(a, location);
    
return true;
  
}

  
public void act()
  
{
    
for (Actor actor : getActors())
    
{
      actor.
move(1);
      
if (actor.getX() > 700)
        actor.
removeSelf();
    
}
  
}

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

Execute the program locally using WebStart.

 

floodfill