Here’s a fun little example app. It’s Conway’s Game of Life. Each cell is rendered as a sphere.
You need a file named life_rules.txt to set the properties:
width=100
height=100
texture=tri2.jpg
#divergent gliders
#rows=5
#row0=111110000001000
#row1=100001000100010
#row2=100000000000001
#row3=010001000100001
#row4=000100000011111
#star
rows=5
row0=10101
row1=10001
row2=10001
row3=10001
row4=10101
And here is the code for it:
import java.io.*;
import java.util.Properties;
import java.util.Enumeration;
import com.jme.app.SimpleGame;
import com.jme.bounding.*;
import com.jme.math.Vector3f;
import com.jme.scene.shape.*;
import com.jme.scene.state.*;
import com.jme.util.*;
import com.jme.image.*;
import com.jme.scene.*;
import com.jme.renderer.ColorRGBA;
import com.jme.input.*;
import com.jme.light.*;
public class Life extends SimpleGame
{
private Node scene;
private Vector3f currentPos;
int width = 100;
int height = 100;
int thisData[][] = new int[width][height];
int nextData[][] = new int[width][height];
Sphere cells[][] = new Sphere[width][height];
TextureState ts = null;
Timer timer = null;
float lastTime = -3.0f;
public static void main(String[] args)
{
Life app = new Life();
app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
app.start();
}
protected void simpleUpdate()
{
if(timer.getTimeInSeconds() > lastTime + 1.0f)
{
//display
for(int x=0; x<width; x++){for(int y=0; y<height; y++){
if(thisData[x][y] == 0)
{
if(cells[x][y] != null){scene.detachChild(cells[x][y]); cells[x][y] = null;}
}
else
{
if(cells[x][y] == null)
{
Sphere s1 = new Sphere("Sphere", new Vector3f(x*2 - width, y*2 - height, -20), 10, 10, 1);
cells[x][y] = s1;
s1.setModelBound(new BoundingBox());
s1.updateModelBound();
s1.setRenderState(ts);
s1.updateRenderState();
scene.attachChild(s1);
}
}
}}
//update
for(int x=1; x<width-1; x++){for(int y=1; y<height-1; y++){
int nbrAround = thisData[x-1][y-1] + thisData[x][y-1] + thisData[x+1][y-1] +
thisData[x-1][y] + thisData[x+1][y] +
thisData[x-1][y+1] + thisData[x][y+1] + thisData[x+1][y+1];
if(thisData[x][y] == 0)
{
if(nbrAround == 3)
{
nextData[x][y] = 1;
}
else
{
nextData[x][y] = 0;
}
}
else
{
if(nbrAround < 2 || nbrAround > 3)
{
nextData[x][y] = 0;
}
else
{
nextData[x][y] = 1;
}
}
}}
for(int x=1; x<width-1; x++){for(int y=1; y<height-1; y++){
thisData[x][y] = nextData[x][y];
}}
lastTime = timer.getTimeInSeconds();
}
}
protected void simpleInitGame()
{
display.setTitle("3D Life");
scene = new Node("3D Life");
timer = Timer.getTimer(properties.getRenderer());
PropertyReader properties = new PropertyReader("life_rules.txt");
width = Integer.parseInt(properties.getProperty("width"));
height = Integer.parseInt(properties.getProperty("height"));
thisData = new int[width][height];
nextData = new int[width][height];
cells = new Sphere[width][height];
//initializes
for(int x=0; x<width; x++){for(int y=0; y<height; y++){
thisData[x][y] = 0;
nextData[x][y] = 0;
}}
String texture = properties.getProperty("texture");
int rows = Integer.parseInt(properties.getProperty("rows"));
int maxWidth = 0;
int thisWidth = 0;
for(int r=0; r<rows; r++)
{
thisWidth = properties.getProperty("row" + r).length();
if(thisWidth > maxWidth){maxWidth = thisWidth;}
}
int xOffset = width/2 - maxWidth;
int yOffset = height/2 - rows;
for(int r=0; r<rows; r++)
{
String row = properties.getProperty("row" + r);
thisWidth = row.length();
for(int c=0; c<thisWidth; c++)
{
if(row.charAt(c) == '0'){thisData[xOffset + c][yOffset + r] = 0;}
else{thisData[xOffset + c][yOffset + r] = 1;}
}
}
ts = display.getRenderer().getTextureState();
ts.setEnabled(true);
ts.setTexture(
TextureManager.loadTexture(
Life.class.getClassLoader().getResource(
texture),
Texture.MM_LINEAR,
Texture.FM_LINEAR,
true));
rootNode.attachChild(scene);
CullState cs = display.getRenderer().getCullState();
cs.setCullMode(CullState.CS_BACK);
cs.setEnabled(true);
rootNode.setRenderState(cs);
}
}
class PropertyReader
{
private Properties properties;
public PropertyReader(String file)
{
try
{
properties = new Properties();
FileInputStream propFile = new FileInputStream(file);
properties.load(propFile);
propFile.close();
}
catch(Exception e){e.printStackTrace();}
}
public String getProperty(String key)
{
return (String)properties.getProperty(key);
}
public Enumeration propertyNames()
{
return properties.propertyNames();
}
}