📄 wormpit.java
字号:
package worm;
import java.lang.System;
import java.lang.Runnable;
import java.lang.InterruptedException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.media.Player;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.control.ToneControl;
public class WormPit extends Canvas implements Runnable {
/** Handle to target food. */
private WormFood myFood;
/** Handle to current worm object. */
private Worm myWorm;
/** Flag to indicate when the game is finished. */
private boolean gameOver = false;
/** Flag to indicate if current game is paused. */
private boolean gamePaused = false;
/** Flag to indicate game is restarted. */
private boolean gameRestart = false;
/** Flag to indicate forced repaint is needed. */
private boolean forceRedraw = true;
/** Flag to indicate the game is to be completely destroyed. */
private boolean gameDestroyed = false;
/** Current game score. */
private int score = 0;
/** Current game level. */
private int level = 5;
/** Number of pieces of food eaten since the last level change. */
private int foodEaten = 0;
/** Current screen width in pixels. */
private int width;
/** Current screen height in pixels. */
private int height;
/** Audio player for background tune. */
private Player audioPlayer;
/** Tone player. */
private Player tonePlayer;
/** Current screen size in cells. */
static int CellWidth;
/** Current screen height in cells. */
static int CellHeight;
/** Initial offset for screen rendering. */
private static final int START_POS = 3;
/** Font height for rendering the score message. */
private static final int SCORE_CHAR_HEIGHT;
/** Font width for rendering the score message. */
private static final int SCORE_CHAR_WIDTH;
/** Height for two lines of score message text. */
private static final int SCORE_HEIGHT;
/** Default delay between worm repaints. (400 milliseconds) */
private static final int DEFAULT_WAIT = 400;
/** Maximum number of difficulty levels. (10) */
static final byte MAX_LEVELS = 10;
/** Color for target food object. (0x00ff00) */
static final int FOOD_COLOUR = 0x0000ff00;
/** Color for text objects. (0xff0000) */
static final int TEXT_COLOUR = 0x00ff0000;
/** Color for erasing worm cells. (0xffffff) */
static final int ERASE_COLOUR = 0x00ffffff;
/** Color for drawing worm cells. (0x000000) */
static final int DRAW_COLOUR = 0x00000000;
/** Size of a cell for worm rendering. */
public static final int CELL_SIZE = 5;
static {
Font defaultFont = Font.getDefaultFont();
SCORE_CHAR_WIDTH = defaultFont.charWidth('S');
SCORE_CHAR_HEIGHT = defaultFont.getHeight();
SCORE_HEIGHT = SCORE_CHAR_HEIGHT * 2;
}
/**
* Default constructor for worm pit.
* Initialized the food and worm objects.
*/
public WormPit() {
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();
}
}
/**
* Round the given value to next lowest number divisible by the
* cell size.
* @param val number to be rounded down
* @return rounded down value
*/
private int round(int val) {
int delta = (val-(START_POS*2)) % CELL_SIZE;
return (val - delta);
}
/**
* 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.
* @param level value of new level requested
* @see #getLevel
*/
public void setLevel(int level) {
if (this.level != level) {
this.level = level;
gameOver = true;
gamePaused = false;
foodEaten = 0;
score = 0;
}
}
/**
* Get the difficulty level.
* @return current game level
* @see #setLevel
*/
public int getLevel() {
return level;
}
/**
* Get the score of this game.
* @return current score
*/
public int getScore() {
return score;
}
/**
* Returns true if the given point is within the bounds of the
* worm pit.
* @param x x coordinate of point to check (0 - CellWidth)
* @param y y coordinate of point to check (0 - CellHeight)
* @return true, if coordinate is in the worm pit
*/
static boolean isInBounds(int x, int y) {
if ((x < 0) || (x >= WormPit.CellWidth)) {
return false;
}
if ((y < 0) || (y >= WormPit.CellHeight)) {
return false;
}
return true;
}
/**
* Restart the game.
*/
void restart() {
if (gamePaused) {
gamePaused = false;
} else {
myWorm.regenerate();
myFood.regenerate();
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();
}
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();
}
}
/**
* Handle keyboard input. This is used for worm movement.
* @param keyCode pressed key is either Canvas arrow key (UP,
* DOWN, LEFT, RIGHT) or simulated with KEY_NUM (2, 8, 4,6).
*/
public void keyPressed(int keyCode) {
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;
}
}
/**
* Paint anything currently in the pit.
* Overrides Canvas.paint.
* @param g graphics object to be rendered
*/
private void paintPitContents(Graphics g) {
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++;
/*
* End of game - no more levels.
*/
if (level == MAX_LEVELS) {
level--;
gameOver = true;
}
if (tonePlayer != null) {
try {
tonePlayer.setMediaTime(0);
tonePlayer.start();
} catch (MediaException me) { }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -