贪吃蛇的算法分析(4)
James @ www.chenshen.com
WormPit类
WormPit类中包括了Worm和WormFood。贪吃蛇将会在画面中移动寻找食物。如果它吃到食物它将会长一格。如果它碰到边界或者吃到自己将Game Over。
下面介绍几个重要的函数:
l private void paintPitContents(Graphics g)
重绘屏幕上的所有元素
// 更新贪吃蛇的状态
myWorm.update(g);
// 头部的位置和食物的位置重合就吃到食物
if (myFood.isAt(myWorm.getX(), myWorm.getY())) {
myWorm.eat();
score += level;
foodEaten++;
if (foodEaten > (level << 1)) {
/* 增加游戏难度 */
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);
// 显示新的分数
g.drawString("" + score,
width - (SCORE_CHAR_WIDTH * 3) - START_POS,
height - START_POS, Graphics.TOP|Graphics.LEFT);
// 重新生成食物
myFood.regenerate();
int x = myFood.getX();
int y = myFood.getY();
while (myWorm.contains(x, y)) {
// 如果食物和贪吃蛇的身体重复就重新生成
myFood.regenerate();
x = myFood.getX(); y = myFood.getY(); } }
// 画出食物
myFood.paint(g);
} catch (WormException se) { gameOver = true; }
l public void run()
主循环体:
while (!gameDestroyed) { // 游戏不终止就一直循环执行
try {
synchronized (myWorm) { // 多线程中要进行同步
// 如果游戏结束
if (gameOver) {
if (WormScore.getHighScore(level) < score) {
// 把最高分保存
WormScore.setHighScore(level, score, "me"); }
if ((audioPlayer != null) &&
(audioPlayer.getState() == Player.STARTED)) {
try {
audioPlayer.stop();
Manager.playTone(60, 400, 100);
} catch (Exception ex) { } }
// 重绘
repaint();
// 游戏结束时等待用户重新开始
myWorm.wait();
} else if (gamePaused) {
//重绘
repaint();
// 游戏暂停时等待用户重新开始
myWorm.wait();
} else {
// 游戏继续
myWorm.moveOnUpdate();
repaint();
// 这里的等待时间决定了游戏难度!!!
myWorm.wait(DEFAULT_WAIT-(level*40));
}
}
} catch (java.lang.InterruptedException ie) {
}
}
关于作者:
沈晨,高级程序员,SCJP
August 10, 2003