July 30, 2005
The applets we've seen so far here all inherit
their basic properties from Applet through the use of the word
extends, for example in
the line
public class
Mondrian2 extends
Applet {
which
means that the derived class
Mondrian2
will inherit the parent class Applet's
public variables and methods, such as
paint(). Since
Mondrian2
"is an" Applet, the use of inheritance is appropriate. In
java, all classes are derivative of the mother class,
Object. Even if the "extends"
keyword is omitted, the public and protected methods of
Object are inherited by default.
I'll
try to annotate this as best I can. Here's what I've got for
today:
import java.applet.*;
import java.awt.*;
import java.util.*;
//This is for the Random() function
public class Mondrian4
extends
Applet implements Runnable {
Thread animation;
Graphics offscreen;
Image image;
static final int NUM_RECTS =
9; //in ms
static final int
REFRESH_RATE = 100; //in ms
MovingRect rek[];
public void init() {
System.out.println(">> init <<");
setBackground(Color.black);
initRectangles();
image = createImage(bounds().width,bounds().height);
offscreen = image.getGraphics();
}
public void initRectangles() {
// allocate memory for Moving rectangles
rek = new MovingRect[NUM_RECTS];
rek[0] = new
MovingRect(0,0,90,90,Color.yellow);
rek[1] = new
BoogieRect(250,0,40,190,Color.yellow);
rek[2] = new
WaltzRect(200,55,60,135,Color.yellow);
rek[3] = new
BoogieRect(80,200,220,90,Color.blue);
rek[4] = new
WaltzRect(100,10,90,80,Color.blue);
rek[5] = new
BoogieRect(80,100,110,90,Color.lightGray);
rek[6] = new
WaltzRect(200,0,45,45,Color.red);
rek[7] = new
WaltzRect(0,100,70,200,Color.red);
rek[8] = new
BoogieRect(200,55,60,135,Color.magenta);
}
public void start() {
System.out.println(">>
start <<");
animation = new
Thread(this);
if (animation
!= null)
{
animation.start();
}
}
// update each rectangle's position.
// This is the dynamic
method binding--Movement() is over-ridden
// for individual
choreography!
public void updateRectangles() {
for (int
i=0; i<NUM_RECTS;
i++) {
rek[i].Movement(); // each
rectangle's Movement
}
}
// override update so it doesn't erase screen
public void update(Graphics
g) {
paint(g);
}
public void paint(Graphics
g) {
offscreen.setColor(Color.black);
offscreen.fillRect(0,0,300,300); //
clear buffer
for (int i=0;
i<NUM_RECTS; i++)
{
rek[i].paint(offscreen); //
paint each rectangle
}
g.drawImage(image,0,0,this);
}
public void run() {
while (true)
{
repaint();
updateRectangles();
try {
Thread.sleep
(REFRESH_RATE);
} catch (Exception
exc) { };
}
}
public void stop() {
System.out.println(">>
stop <<");
if (animation !=
null) {
animation.stop();
animation = null;
}
}
}
/////////////////////////////////////////////////////////////////
class MovingRect {
int ulCornx, ulCorny;
// (ulCornx,ulCornyy) are coordinates of
upper
// left corner of rectangle
int width, height;
// width and height of rectangle
Color rectColor; //
color of rectangle
/////////////////////////////////////////////////////////////////
public MovingRect(int
x,int y,int
w,int h,Color
c) {
ulCornx = x;
ulCorny = y;
width = w;
height = h;
rectColor = c;
}
public void
Movement() {
// this is just a placeholder for
dynamic binding
}
public void paint(Graphics
g) {
g.setColor(rectColor);
g.fillRect(ulCornx,ulCorny,width,height);
}
}
/////////////////////////////////////////////////////////////////
class BoogieRect
extends MovingRect {
Random r1 =
new Random();
//add a touch of unpredictability to motion
// BoogieRect inherits all instance variables and
// methods from MovingRect
static final byte UP = 0; // direction of
motion
static final byte DOWN = 1;
static final byte LEFT = 2;
static final byte RIGHT = 3;
byte state; // state
of rectangle
int max_x; // max x value
int min_x; // min x value
int max_y; // max y value
int min_y; // min y value
/////////////////////////////////////////////////////////////////
public BoogieRect(int
x,int y,int
w,int h,Color
c) {
super(x,y,w,h,c); // call superclass
constructor
int i = r1.nextInt()%4;
int j = r1.nextInt()%8;
max_x = ulCornx + 13 + i;
min_x = ulCornx - 13;
max_y = ulCorny + 13+j;
min_y = ulCorny - 13;
}
// override MoveStep()
public void Movement() {
switch (state) {
case DOWN:
ulCorny += 2;
if (ulCorny
>= max_y) {
state = UP;
}
break;
case
UP:
ulCorny -= 2;
if (ulCorny <= min_y) {
state = RIGHT;
}
break;
case
RIGHT:
ulCornx += 2;
if (ulCornx >=
max_x) {
state = LEFT;
}
break;
case LEFT:
ulCornx -= 2;
if (ulCornx <=
min_x) {
state = DOWN;
}
break;
}
}
}
/////////////////////////////////////////////////////////////////
// WaltzRect also inherits from MovingRect
class WaltzRect
extends MovingRect {
byte state;
static final
byte SE = 0;
// going southeast
static final
byte NE = 1;
// going northeast
static final
byte W = 2;
// going west
int bottom_x; // the x
coordinate of
// bottom pt of the waltz
int right_x;
// the x coordinate of
// right pt of the waltz
int left_x; // the x
coordinate of
// left pt of the waltz
/////////////////////////////////////////////////////////////////
public WaltzRect(int
x,int y,int
w,int h,Color
c) {
super(x,y,w,h,c); //
call superclass constructor
bottom_x = ulCornx + 17;
right_x = bottom_x + 17;
left_x = ulCornx;
}
// override Movement()
public void Movement() {
switch (state) {
case SE:
ulCornx++;
ulCorny++;
if (ulCornx
== bottom_x) {
state = NE;
}
break;
case NE:
ulCornx++;
ulCorny--;
if (ulCornx ==
right_x) {
state = W;
}
break;
case W:
ulCornx-- ;
if (ulCornx ==
left_x) {
state = SE;
}
break;
}
}
}
It's odd: when I compile and run stand-alone, the rectangles go
flying around, but when I try to access the Applet via the internet
using IE5, they're stuck still in the solid mud...do they move for
you? To be sure, I used my son's Windows 2000/Firefox set up
and (after long interlude downloading and installing the java
runtime environment), lo and behold, the rectangles are moving!
Hmmm. After a reboot, they're moving again on my computer, so
go figure...
|