WormPitpublic class WormPit extends javax.microedition.lcdui.Canvas implements RunnableThe WormPit contains a Worm and some WormFood. The Worm will
slither around the pit in search of WormFood. If the Worm eats
it will grow in length. The Worm will be killed if it attempts
to slither past the edge of the pit or if it eats itself. |
Fields Summary |
---|
private WormFood | myFoodHandle to target food. | private Worm | myWormHandle to current worm object. | private boolean | gameOverFlag to indicate when the game is finished. | private boolean | gamePausedFlag to indicate if current game is paused. | private boolean | gameRestartFlag to indicate game is restarted. | private boolean | forceRedrawFlag to indicate forced repaint is needed. | private boolean | gameDestroyedFlag to indicate the game is to be completely destroyed. | private int | scoreCurrent game score. | private int | levelCurrent game level. | private int | foodEatenNumber of pieces of food eaten since the last level change. | private int | widthCurrent screen width in pixels. | private int | heightCurrent screen height in pixels. | private javax.microedition.media.Player | audioPlayerAudio player for background tune. | private javax.microedition.media.Player | tonePlayerTone player. | static int | CellWidthCurrent screen size in cells. | static int | CellHeightCurrent screen height in cells. | private static final int | START_POSInitial offset for screen rendering. | private static final int | SCORE_CHAR_HEIGHTFont height for rendering the score message. | private static final int | SCORE_CHAR_WIDTHFont width for rendering the score message. | private static final int | SCORE_HEIGHTHeight for two lines of score message text. | private static final int | DEFAULT_WAITDefault delay between worm repaints. (400 milliseconds) | static final byte | MAX_LEVELSMaximum number of difficulty levels. (10) | static final int | FOOD_COLOURColor for target food object. (0x00ff00) | static final int | TEXT_COLOURColor for text objects. (0xff0000) | static final int | ERASE_COLOURColor for erasing worm cells. (0xffffff) | static final int | DRAW_COLOURColor for drawing worm cells. (0x000000) | public static final int | CELL_SIZESize of a cell for worm rendering. |
Constructors Summary |
---|
public WormPit()Default constructor for worm pit.
Initialized the food and worm objects.
Font defaultFont = Font.getDefaultFont();
SCORE_CHAR_WIDTH = defaultFont.charWidth('S");
SCORE_CHAR_HEIGHT = defaultFont.getHeight();
SCORE_HEIGHT = SCORE_CHAR_HEIGHT * 2;
width = round(getWidth());
height = round(getHeight()-SCORE_HEIGHT);
WormPit.CellWidth = (width-(START_POS*2)) / WormPit.CELL_SIZE;
WormPit.CellHeight = (height-(START_POS*2)) / WormPit.CELL_SIZE;
myWorm = new Worm(this);
/* Generate food for worm to eat */
myFood = new WormFood(this);
int x = myFood.getX();
int y = myFood.getY();
while (myWorm.contains(x, y)) {
myFood.regenerate(); // regenerate if food placed under worm
x = myFood.getX(); y = myFood.getY();
}
|
Methods Summary |
---|
public void | createAudioPlayer()Create an audio player.
byte[] bkmelody = {
ToneControl.VERSION, 1,
ToneControl.SET_VOLUME, 40,
76, 8,
81, 24,
76, 8,
88, 24,
81, 8,
85, 16,
83, 8,
85, 8,
81, 16,
76, 16,
81, 16,
90, 16,
88, 16,
85, 8,
86, 8,
88, 48,
ToneControl.SILENCE, 8,
76, 8,
81, 16,
90, 16,
88, 16,
85, 8,
86, 8,
88, 16,
83, 8,
85, 8,
81, 16,
76, 16,
81, 16,
85, 8,
86, 8,
83, 24,
81, 8,
81, 32
};
byte[] tseq = {
ToneControl.VERSION, 1,
64, 4,
65, 4,
66, 4
};
if (audioPlayer != null) {
audioPlayer.close();
audioPlayer = null;
try {
Thread.sleep(200);
} catch (Exception ex) { }
}
try {
ToneControl tControl;
tonePlayer = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
tonePlayer.realize();
tControl = (ToneControl)tonePlayer.getControl("ToneControl");
tControl.setSequence(tseq);
audioPlayer = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
audioPlayer.setLoopCount(-1);
audioPlayer.realize();
tControl = (ToneControl)audioPlayer.getControl("ToneControl");
tControl.setSequence(bkmelody);
audioPlayer.start();
} catch (Exception ex) {
ex.printStackTrace();
}
| public void | destroyAudioPlayer()Destroy the audio player. Call this destroy the audio player.
synchronized (myWorm) {
if (audioPlayer != null) {
audioPlayer.close();
audioPlayer = null;
}
if (tonePlayer != null) {
tonePlayer.close();
tonePlayer = null;
}
myWorm.notifyAll();
}
| public void | destroyGame()Destroy the entire game. Call this prior to destroying the MIDlet.
synchronized (myWorm) {
gameDestroyed = true;
//myWorm.notifyAll();
myWorm.notifyAll();
}
| public int | getLevel()Get the difficulty level.
return level;
| public int | getScore()Get the score of this game.
return score;
| protected void | hideNotify()Notification handler when canvas hidden.
Forces a redraw when canvas is shown again.
Signals that the game is paused while the canvas is obscured.
super.hideNotify();
forceRedraw = true;
if (!gameOver) {
gamePaused = true;
}
| static boolean | isInBounds(int x, int y)Returns true if the given point is within the bounds of the
worm pit.
if ((x < 0) || (x >= WormPit.CellWidth)) {
return false;
}
if ((y < 0) || (y >= WormPit.CellHeight)) {
return false;
}
return true;
| public void | keyPressed(int keyCode)Handle keyboard input. This is used for worm movement.
switch (getGameAction(keyCode)) {
case Canvas.UP:
myWorm.setDirection(Worm.UP);
break;
case Canvas.DOWN:
myWorm.setDirection(Worm.DOWN);
break;
case Canvas.LEFT:
myWorm.setDirection(Worm.LEFT);
break;
case Canvas.RIGHT:
myWorm.setDirection(Worm.RIGHT);
break;
case 0:
// There is no game action.. Use keypad constants instead
switch (keyCode) {
case Canvas.KEY_NUM2:
myWorm.setDirection(Worm.UP);
break;
case Canvas.KEY_NUM8:
myWorm.setDirection(Worm.DOWN);
break;
case Canvas.KEY_NUM4:
myWorm.setDirection(Worm.LEFT);
break;
case Canvas.KEY_NUM6:
myWorm.setDirection(Worm.RIGHT);
break;
}
break;
}
| public void | paint(javax.microedition.lcdui.Graphics g)Paint the worm pit and its components
if (forceRedraw) {
// Redraw the entire screen
forceRedraw = false;
// Clear background
g.setColor(WormPit.ERASE_COLOUR);
g.fillRect(0, 0, getWidth(),
getHeight());
// Draw pit border
g.setColor(WormPit.DRAW_COLOUR);
g.drawRect(1, 1, (width - START_POS), (height - START_POS));
// Display current level
g.drawString("L: " + level, START_POS, height, g.TOP|g.LEFT);
g.drawString("" + score,
(width - (SCORE_CHAR_WIDTH * 3)),
height, g.TOP|g.LEFT);
// Display current score
g.drawString("S: ",
(width - (SCORE_CHAR_WIDTH * 4)),
height, g.TOP|g.RIGHT);
g.drawString("" + score,
(width - (SCORE_CHAR_WIDTH * 3)),
height, g.TOP|g.LEFT);
// Display highest score for this level
g.drawString("H: ",
(width - (SCORE_CHAR_WIDTH * 4)),
(height + SCORE_CHAR_HEIGHT),
g.TOP|g.RIGHT);
g.drawString("" + WormScore.getHighScore(level),
(width - (SCORE_CHAR_WIDTH * 3)),
(height + SCORE_CHAR_HEIGHT),
g.TOP|g.LEFT);
// Draw worm & food
g.translate(START_POS, START_POS);
g.setClip(0, 0, CellWidth*CELL_SIZE, CellHeight*CELL_SIZE);
myWorm.paint(g);
myFood.paint(g);
} else {
// Draw worm & food
g.translate(START_POS, START_POS);
}
if (gamePaused) {
Font pauseFont = g.getFont();
int fontH = pauseFont.getHeight();
int fontW = pauseFont.stringWidth("Paused");
g.setColor(WormPit.ERASE_COLOUR);
g.fillRect((width-fontW)/2 - 1, (height-fontH)/2,
fontW + 2, fontH);
g.setColor(WormPit.TEXT_COLOUR);
g.setFont(pauseFont);
g.drawString("Paused", (width-fontW)/2, (height-fontH)/2,
g.TOP|g.LEFT);
} else if (gameOver) {
Font overFont = g.getFont();
int fontH = overFont.getHeight();
int fontW = overFont.stringWidth("Game Over");
g.setColor(WormPit.ERASE_COLOUR);
g.fillRect((width-fontW)/2 - 1, (height-fontH)/2,
fontW + 2, fontH);
g.setColor(WormPit.TEXT_COLOUR);
g.setFont(overFont);
g.drawString("Game Over", (width-fontW)/2, (height-fontH)/2,
g.TOP|g.LEFT);
} else {
paintPitContents(g);
}
g.translate(-START_POS, -START_POS);
| private void | paintPitContents(javax.microedition.lcdui.Graphics g)Paint anything currently in the pit.
Overrides Canvas.paint.
try {
myWorm.update(g); // update worm position
if (myFood.isAt(myWorm.getX(), myWorm.getY())) {
myWorm.eat();
score += level;
foodEaten++;
if (foodEaten > (level << 1)) {
/* Increase difficulty level */
forceRedraw = true;
foodEaten = 0;
level++;
if (tonePlayer != null) {
try {
tonePlayer.setMediaTime(0);
tonePlayer.start();
} catch (MediaException me) { }
}
} else {
if (audioPlayer != null) {
try {
Manager.playTone(69, 50, 100); // Play audio
} catch (MediaException me) { }
}
}
g.setColor(WormPit.ERASE_COLOUR);
g.fillRect((width - (SCORE_CHAR_WIDTH * 3))-START_POS,
height-START_POS,
(SCORE_CHAR_WIDTH * 3),
SCORE_CHAR_HEIGHT);
g.setColor(WormPit.DRAW_COLOUR);
// Display new score
g.drawString("" + score,
width - (SCORE_CHAR_WIDTH * 3) - START_POS,
height - START_POS, g.TOP|g.LEFT);
myFood.regenerate();
int x = myFood.getX();
int y = myFood.getY();
while (myWorm.contains(x, y)) {
// generate again if food placed under worm..
myFood.regenerate();
x = myFood.getX(); y = myFood.getY();
}
}
myFood.paint(g);
} catch (WormException se) {
gameOver = true;
}
| void | restart()Restart the game.
if (gamePaused) {
gamePaused = false;
} else {
myWorm.regenerate();
myFood.regenerate();
foodEaten = 0;
score = 0;
gameOver = false;
if ((audioPlayer != null) &&
(audioPlayer.getState() == Player.PREFETCHED)) {
try {
audioPlayer.setMediaTime(0);
audioPlayer.start();
} catch (MediaException me) { }
}
}
forceRedraw = true;
synchronized (myWorm) {
myWorm.notifyAll();
}
| private int | round(int val)Round the given value to next lowest number divisible by the
cell size.
int delta = (val-(START_POS*2)) % CELL_SIZE;
return (val - delta);
| public void | run()The main execution loop.
while (!gameDestroyed) {
try {
synchronized (myWorm) {
if (gameOver) {
if (WormScore.getHighScore(level) < score) {
/* Display score screen */
WormScore.setHighScore(level, score, "me");
}
if ((audioPlayer != null) &&
(audioPlayer.getState() == Player.STARTED)) {
try {
audioPlayer.stop();
Manager.playTone(60, 400, 100);
} catch (Exception ex) { }
}
repaint();
// serviceRepaints(); // Draw immediately
myWorm.wait(); // Wait until user presses 'restart'
} else if (gamePaused) {
repaint();
// serviceRepaints(); // Draw immediately
myWorm.wait(); // Wait until user presses 'restart'
} else {
myWorm.moveOnUpdate();
repaint();
// serviceRepaints(); // Draw immediately
myWorm.wait(DEFAULT_WAIT-(level*40));
}
}
} catch (java.lang.InterruptedException ie) {
}
}
| public void | setLevel(int level)Set the difficulty level. If the new level is different from the
current level, any game currently in progress is terminated and
the score is lost.
if (this.level != level) {
this.level = level;
gameOver = true;
gamePaused = false;
foodEaten = 0;
score = 0;
}
|
|