Uploaded to www.rart.com/j2me-presentation/html_Source/ March 19, 2002
This is an example of a Rart universe ported to the J2ME environment. See the use of the ColorME class.
Lines also uses the small EndPoint class, the source for which we also have provided here.
This version has been tested with j2mewtk 1.0.2 and 1.0.3
/*
* @LinesME 1.0 010915
*
* © A-Square, Inc.
* 1648 Waters Edge Lane, Reston Virginia, 20190, USA
*/
package rartme.univ;
import javax.microedition.lcdui.*;
import rartme.*;
/**
* Lines universe
*
* Source: LinesME.java
* Description: Displays a window with lines that wander across the screen.
* When the endpoints rech the border, they bounce off in random directions.
* There are a number of lines on the screen at the time and they change
* color as they progress. The original Rart Lines universe was programmed
* in QuickBasic for the Macintosh around 1985.
*
* This version is adapted to J2ME and the first real universe to be
* programmed in the ME environment. With a color display there are
* options to select background from the standard Java colors using the
* ColorME class.
* Released as a sample universe for RartME, September 2001
* Proud Author: Jan Aminoff
*/
public final class LinesME extends UniverseME {
// Section 1 Identifying the Universe
// ------------------------------------------------------------------------
public String getName(){ // Name
return("LinesME");} // Name of the universe.
public String getDescription(){
return(sd);}
private String sd= // Description
" In the Lines Universe two end points are "+
"stepped streight until they bounce randomly "+
"against the edge of the display. Lines join the two end "+
"points for each step.";
public String getRartist(){
return("Jan Aminoff 2001");} // Name of Rartist.
// end of Section 1
// Section 2 What the universe does
// -----------------------------------------------------------------------
private static int nn_max=xm/2; // Max half of screen covred with lines
// The endpoints of the lines are saved in the following two arrays
private Point p1s[] = new Point[nn_max];
private Point p2s[] = new Point[nn_max];
// The EndPoints are the ones moving generating new lines as they move
private EndPoint p1; // first EndPoint
private EndPoint p2; // second EndPoint
private int m; // current index to point array
private boolean color;
private boolean resetScreen=false; // Flag to reset the screen as needed.
private DebugME dB; // Here if needed. See init.
public void init(){
// Following establishes a pattern for setting and use of Debug.
/*
* Set debuglevel to 2 or higher for tracing output.
* You can set it here for this class only or for all rartme
* classes in the JAD file (Usually RartME.jad) from where it
* is available in Universe as protected int dblevel;
*/
int dblvl = 0; // Set dblevel here for this universe
dblevel = Math.max(dblvl,dblevel);
dB= new DebugME(true);
dB.setLevel(dblevel);
dB.dbg(1,"LinesME.init, dblevel "+dblevel);
dB.dbg(3, "LinesME.init, nn_max "+nn_max);
color = (numColor>0);
setParams();
reset();
}
/**
* reset is used in init and also in manageChange when uParameters speed
* (with index VIEWSIZE) and number (with index NUMBER) have changed.
*/
private void reset(){
vv = speed.getCur(); // current maximum speed
nn = number.getCur(); // current number of lines
// xm and ym are available from universe
p1 = new EndPoint(xm,ym,vv); // first EndPoint
p2 = new EndPoint(xm,ym,vv); // second EndPoint
m=0; // index to current pair of endpoints
// reset the arrays of points
for (int i = 0; i<nn; i++){
p1s[i]=new Point(0,0);
p2s[i]=new Point(0,0);
}
// The following deals with the ability to select color
cc=colorcomb.getCur();
dB.dbg(3,"LinesME.reset, line 106, cc, color " +
cc+", "+((cc>1)? ColorME.colornames[cc-2]:((cc>0)?
"wh on bl":"bl on Wh")));
if (cc==0) {
colorlines = false;
lineColor = ColorME.BLACK;
background = ColorME.WHITE;
}else if (cc==1){
colorlines = false;
lineColor = ColorME.WHITE;
background = ColorME.BLACK;
}else{
colorlines = true;
background = ColorME.colorvalues[cc-2];
}
resetScreen=true;
} //end of reset
public void cycle (Graphics g){
if (resetScreen){
//g.setPaintMode();
g.setColor(background);
g.fillRect(0,0,xm,ym);
resetScreen = false;
}
// Save p1 and p2 as points in point arrays
p1s[m]=new Point(p1);
p2s[m]=new Point(p2);
//Update position of the two end points
p1.move();
p2.move();
// Step index to point arrays
m= (m+1) % nn;
// If we have been there, disappear the former line
if ((p1s[m].x!=0)&& (p1s[m].y!=0)){
g.setColor(background);
g.drawLine(p1s[m].x, p1s[m].y, p2s[m].x, p2s[m].y);
}
if (colorlines) {
// Step line color
hue++;
lineColor = ColorME.mkColorfromHue(hue);
hue = hue % 359; // keep going around the color wheel.
}
// Draw Line in color p1 to p
g.setColor(lineColor);
g.drawLine(p1.x, p1.y, p2.x, p2.y);
} // end of cycle
// Color stuff
/* In the enhancement introduced as Ex5b there are three variations of
* the Lines universe: Black lines on white, white lines on black, and
* lineColor stepped through 360 colors on a selectable background.
* The third version is distingushed by the boolean colorlines being true.
* The first two versions are distinguised by colorlines being false and
* the boolean blackonwhite being either true or false.
*
* Default is colorlines being true.
*/
private int cc=2; //Default choice of linecolor varying on white
private boolean colorlines=true;
private boolean blackonwhite;
private int background = ColorME.BLACK; //Reset in reset
private int lineColor = ColorME.WHITE; //
private int hue = 270;
public void manageChange(uParameter uP){
int idx=uP.getIndex();
//dB.dbg( 2,"Lines.mC, Change in : "+uP.getName());
if (uPs[idx]!=null) uPs[idx]=uP; //ensures that uPs, the list of current parameters is up to date
switch (idx){
case NUMBER:
number=uP;
reset();
break;
case PARA4: //used for speed or actually density
// do not need to reset here but need to reset max speed in
// the two EndPoints
speed=uP;
vv=speed.getCur();
p1.setMaxSpeed(vv);
p2.setMaxSpeed(vv);
break;
case PARA5: // for new colorcombinations
colorcomb=uP;
reset();
break;
}
} // end manageChange
// end of Section 2
// Section 3 uParameters as used in the universe
// -----------------------------------------------------------------------
private uParameter number; //Number of lines requested - PARAMETER
private int nn_min=1,nn_cur=nn_max/2; // nn_max is a static variable
private int nn=nn_cur; //actual number of lines
private String ndescr=
"Number of 'Lines' on the "+
"screen at any one time.";
// max speed of any EndPoint in x or y direction - PARAMETER
private uParameter speed;
private int vv=4,vv_max=8,vv_min=1;
private String sdescr=
"The 'Speed' is the maximum speed in pixels.";
// colorcombinations of linecolor on background color - PARAMETER
// The following is new for Ex5b:
private uParameter colorcomb;
private String ccdescr1 =
"Select black lines on white background or white lines on black";
private String ccdescr2 =
" or lines whose color is stepped through 360 shades of color against"+
" a background selected from thirteen primary Java colors.";
static String colornames1[]={ " Black on White", " White on Black"};
static String colornames2[]= { " Black on White", " White on Black",
" Black", " Blue", " Cyan",
" Dark grey", " Grey",
" Green", " Light grey", " Magenta",
" Orange", " Pink", " Red",
" White", " Yellow"};
// cycletime is set here but otherwise handled in the rartrunners
public uParameter cycletime;
private void setParams(){
number= new uParameter
(NUMBER,"Number of Lines",nn_min,nn_cur,nn_max,ndescr);
// The adduParameter() method is defined in Universe
adduParameter(number);
speed=new uParameter(PARA4,"Speed",vv_min,vv, vv_max, sdescr);
adduParameter(speed);
String ccd = ccdescr1;
ccd +=(color)? ccdescr2:".";
colorcomb = new uParameter
(PARA5,"Color Combination",cc,
(color)? colornames2:colornames1, ccd);
adduParameter(colorcomb);
// Since "Cycle Time" is a compulsory parameter, Universe actually
// provides the description
cycletime= new uParameter(CYCLETIME,"Cycle Time", 10,25,100, CycleTimeDescr);
adduParameter(cycletime);
} // end of params
// Security related constructor
public LinesME() throws InstantiationException {}
} // End of class Lines
/*
*
* EndPoint 1.0 010915
*
* © A-Square, Inc.
* 1648 Waters Edge Lane, Reston Virginia, 20190, USA
*/
package rartme.univ;
import rartme.*;
/**
* Class: EndPoint, the EndPoint moves in steps of fixed increments (or
* speed)across the screen until it hits a border when it is redirected in
* a new direction with a new speed.
*
* Released as a component of the LinesME sample universe, September 2001
*/
public class EndPoint extends Point {
public static int BORDERWIDTH=2; // EndPoints bounce when coming within
// BORDERWIDTH pixels of any edge of the screen
private int bw=BORDERWIDTH; // just to save typing
private int dx; // current velocity in x dir
private int dy; // current velocity in y dir
private int xm; // width of window set in constructor
private int ym; // height of window set in constructor
private int vv; // maximum speed of point set in constructor
/**
* Constructor
* The initial poition of an endpoint is within the rectangle described by
* (bw, bw, x_max-2*bw, y_max-2*bw) where bw is the BORDERWIDTH.
*
* @x_max the width of the window in pixels
* @y_max the height of the window in pixels
* @v_max the maximum stepping speed of the EndPoint
*/
EndPoint(int x_max, int y_max, int v_max) {
xm=x_max;
ym=y_max;
vv=v_max;
setMaxSpeed(vv);
x = bw+RND(x_max-2*bw);
y = bw+RND(y_max-2*bw);
dx = setSpeed(vv);
dy = setSpeed(vv);
} // end EndPoint constructor
/**
* sets the maximum speed in x and y direction
*
* @v speed, greater than 0 and smaller than 50
*/
public void setMaxSpeed(int v){
v= (v<1)? 1: (v>50)? 50: v;
vv=v;
} // end setMaxSpeed
/**
* The move method encapsulates the behaviour where a point is stepped in
* discrete increments (dx and dy) until it hits an edge when its
* direction is reversed and the speed paralell to the edge given a new
* random value, effectively bouncing the point at random.
*
*/
public void move(){
x += dx; //Step x
y += dy; //Step y
// Check to see if the point hit the edge in x-direction
if (x < bw || x > (xm - bw)){
dx = (x<bw)? ABS(dx):-ABS(dx); // always moving toward center
x += 2*dx; // double back
dy = setSpeed(vv); // change speed in y-direction
}
// Check to see if the point hit the edge in y-direction
if (y < bw || y > (ym - bw)){
dy = (y<bw)? ABS(dy):-ABS(dy); // always moving toward center
y += 2*dy; // double back
dx = setSpeed(vv); // change speed in x-direction
}
} // end move
// Following two methods taken from Universe
private static int RND(int x){
return(UniverseME.RND(x));
}
private static int ABS(int x){
return(UniverseME.ABS(x));
}
private int setSpeed(int v){
int v1;
do{
// The following ensures speed distributed randomly in the
// interval [-v , v] endpoints included and 0 excluded.
v1=(RND(3)-1)*(1+RND(v));
}while (v1==0); // speed never 0!
return v1;
} // end of setSpeed
} // End of class EndPoint