FileDocCategorySizeDatePackage
Worm.javaAPI DocJ2ME MIDP 2.06818Thu Nov 07 12:02:20 GMT 2002example.wormgame

Worm

public 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 booleancontains(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 voiddrawLink(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 voideat()
Signals the worm to eat a food item

	hasEaten = true;
    
public intgetX()
Get the X coordinate of the cell that contains the worm's head.

	synchronized (worm) {
	    return ((WormLink)worm.lastElement()).getEndX();
	}
    
public intgetY()
Get the Y coordinate of the cell that contains the worm's head.

	synchronized (worm) {
	    return ((WormLink)worm.lastElement()).getEndY();
	}
    
public voidmoveOnUpdate()
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 voidpaint(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 voidregenerate()
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 voidsetDirection(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 voidupdate(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");
		}
	    }

	}