Wormpublic class Worm extends Object A Worm is a combination of one or more WormLinks. The first
WormLink is the physical tail of the worm. The last WormLink
is the physical head of the worm. As the worm moves, it adds
one space to the head and then removes one from the tail. If the
worm eats a piece of food, the head adds one space but the tail
will not remove one. In this manner, the worm will grow outward
from its head. |
Fields Summary |
---|
public static final byte | DOWN | public static final byte | LEFT | public static final byte | RIGHT | public static final byte | UP | private byte | currentDirection | private Vector | worm | private boolean | needUpdate | private boolean | moveOnNextUpdate | private boolean | hasEaten | private static final int | INIT_X | private static final int | INIT_Y | private static final int | INIT_LEN | private static final byte | INIT_DIR |
Constructors Summary |
---|
public Worm(WormPit pit)
regenerate();
|
Methods Summary |
---|
public boolean | contains(int x, int y)Returns true if the worm contains the given cell coordinate.
WormLink sl;
synchronized (worm) {
for (int i = 0; i < worm.size(); i++) {
sl = (WormLink)worm.elementAt(i);
if (sl.contains(x, y)) {
return true;
}
}
}
return false;
| public void | drawLink(javax.microedition.lcdui.Graphics g, int x1, int y1, int x2, int y2, int len)Draw a worm link.
// Convert coordinates to the drawing area
len *= WormPit.CELL_SIZE;
if (x1 == x2) {
x1 *= WormPit.CELL_SIZE;
if (y2 < y1) {
y1 = y2 * WormPit.CELL_SIZE;
} else {
y1 *= WormPit.CELL_SIZE;
}
g.fillRect(x1, y1, WormPit.CELL_SIZE, len);
} else {
y1 *= WormPit.CELL_SIZE;
if (x2 < x1) {
x1 = x2 * WormPit.CELL_SIZE;
} else {
x1 *= WormPit.CELL_SIZE;
}
g.fillRect(x1, y1, len, WormPit.CELL_SIZE);
}
| public void | eat()Signals the worm to eat a food item
hasEaten = true;
| public int | getX()Get the X coordinate of the cell that contains the worm's head.
synchronized (worm) {
return ((WormLink)worm.lastElement()).getEndX();
}
| public int | getY()Get the Y coordinate of the cell that contains the worm's head.
synchronized (worm) {
return ((WormLink)worm.lastElement()).getEndY();
}
| public void | moveOnUpdate()Schedule the worm for growth. The next time the update()
method is invoked, the worm will move forward by one cell.
synchronized (worm) {
moveOnNextUpdate = true;
}
| public void | paint(javax.microedition.lcdui.Graphics g)Draw the entire worm. Logically, the worm is composed of
one or more links. A worm is usually composed of a few
straight segments. This allows us to paint a full worm
with a minimum of draw calls.
WormLink sl;
int x1, x2, y1, y2;
int len;
for (int i = 0; i < worm.size(); i++) {
sl = (WormLink)worm.elementAt(i);
x1 = sl.getX(); x2 = sl.getEndX();
y1 = sl.getY(); y2 = sl.getEndY();
len = sl.getLength();
drawLink(g, x1, y1, x2, y2, len);
}
| public void | regenerate()Regenerate the worm in its initial position. This is used
to restart the game after the worm is killed.
synchronized (worm) {
worm.removeAllElements();
worm.addElement(new WormLink(INIT_X, INIT_Y,
INIT_LEN, INIT_DIR));
// Reset class variables
currentDirection = INIT_DIR;
needUpdate = false;
hasEaten = false;
moveOnNextUpdate = false;
}
| public void | setDirection(byte direction)Change the direction of the worm. It will only change
directions if you set a direction that is 90 degrees
different from the current direction of the worm.
synchronized (worm) {
if ((direction != currentDirection) && !needUpdate) {
WormLink sl = (WormLink)worm.lastElement();
int x = sl.getEndX();
int y = sl.getEndY();
switch (direction) {
case UP:
if (currentDirection != DOWN) {
y--; needUpdate = true;
}
break;
case DOWN:
if (currentDirection != UP) {
y++; needUpdate = true;
}
break;
case LEFT:
if (currentDirection != RIGHT) {
x--; needUpdate = true;
}
break;
case RIGHT:
if (currentDirection != LEFT) {
x++; needUpdate = true;
}
break;
}
if (needUpdate == true) {
worm.addElement(new WormLink(x, y, 0, direction));
currentDirection = direction;
}
}
}
| public void | update(javax.microedition.lcdui.Graphics g)Update the worm. If the worm is scheduled to grow, this
method will grow the worm head by one cell and potentially
shrink the tail by one cell. If the worm has eaten a piece
of food, the tail will not shrink.
If the worm is not scheduled to grow, this method will
do nothing.
WormLink head, sl;
int headX, headY;
if (!moveOnNextUpdate) {
return;
}
synchronized (worm) {
head = (WormLink)worm.lastElement(); // the worm 'head'
head.increaseLength();
if (!hasEaten) {
WormLink tail;
tail = (WormLink)worm.firstElement(); // the worm 'tail'
int tailX = tail.getX();
int tailY = tail.getY();
tail.decreaseLength();
if (tail.getLength() == 0) {
worm.removeElement(tail);
}
// Clear last block of the tail
g.setColor(WormPit.ERASE_COLOUR);
drawLink(g, tailX, tailY, tailX, tailY, 1);
} else {
hasEaten = false;
}
needUpdate = false;
// Make sure we're still in bounds
if (!WormPit.isInBounds(head.getEndX(), head.getEndY())) {
throw new WormException("over the edge"); // You're dead Jim
}
headX = (byte)head.getEndX();
headY = (byte)head.getEndY();
// Draw the head
g.setColor(WormPit.DRAW_COLOUR);
drawLink(g, headX, headY, headX, headY, 1);
// See if we ate ourself
for (int i = 0; i < worm.size()-1; i++) {
sl = (WormLink)worm.elementAt(i);
if (sl.contains(headX, headY)) {
throw new WormException("you ate yourself");
}
}
}
|
|