//文件名:SnakeMIDlet .Java
package snake;
import Javax.microedition.midlet.*;
import Javax.microedition.lcdui.*;
public class SnakeMIDlet extends MIDlet {
SnakeCanvas displayable = new SnakeCanvas();
public SnakeMIDlet() {
Display.getDisplay(this).setCurrent(displayable);
}
public void startApp() {}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
}
//文件名:SnakeCanvas.Java
package snake;
import Java.util.*;
import Javax.microedition.lcdui.*;
/**
* 貪吃蛇游戲
*/
public class SnakeCanvas extends Canvas implements Runnable{
/**存儲貪吃蛇節點坐標,其中第二維下標為0的代表x坐標,第二維下標是1的代表y坐標*/
int[][] snake = new int[200][2];
/**已經使用的節點數量*/
int snakeNum;
/**貪吃蛇運動方向,0代表向上,1代表向下,2代表向左,3代表向右*/
int direction;
/*移動方向*/
/**向上*/
private final int DIRECTION_UP = 0;
/**向下*/
private final int DIRECTION_DOWN = 1;
/**向左*/
private final int DIRECTION_LEFT = 2;
/**向右*/
private final int DIRECTION_RIGHT = 3;
/**游戲區域寬度*/
int width;
/**游戲區域高度*/
int height;
/**蛇身單元寬度*/
private final byte SNAKEWIDTH = 4;
/**是否處於暫停狀態,true代表暫停*/
boolean isPaused = false;
/**是否處於運行狀態,true代表運行*/
boolean isRun = true;
/**時間間隔*/
private final int SLEEP_TIME = 300;
/**食物的X坐標*/
int foodX;
/**食物的Y坐標*/
int foodY;
/**食物的閃爍控制*/
boolean b = true;
/**Random對象*/
Random random = new Random();
public SnakeCanvas() {
//初始化
init();
width = this.getWidth();
height = this.getHeight();
//啟動線程
new Thread(this).start();
}
/**
* 初始化開始數據
*/
private void init(){
//初始化節點數量
snakeNum = 7;
//初始化節點數據
for(int i = 0;i < snakeNum;i++){
snake[i][0] = 100 - SNAKEWIDTH * i;
snake[i][1] = 40;
}
//初始化移動方向
direction = DIRECTION_RIGHT;
//初始化食物坐標
foodX = 100;
foodY = 100;
}
protected void paint(Graphics g) {
//清屏
g.setColor(0xffffff);
g.fillRect(0,0,width,height);
g.setColor(0);
//繪制蛇身
for(int i = 0;i < snakeNum;i++){
g.fillRect(snake[i][0],snake[i][1],SNAKEWIDTH,SNAKEWIDTH);
}
//繪制食物
if(b){
g.fillRect(foodX,foodY,SNAKEWIDTH,SNAKEWIDTH);
}
}
private void move(int direction){
//蛇身移動
for(int i = snakeNum - 1;i > 0;i--){
snake[i][0] = snake[i - 1][0];
snake[i][1] = snake[i - 1][1];
}
//第一個單元格移動
switch(direction){
case DIRECTION_UP:
snake[0][1] = snake[0][1] - SNAKEWIDTH;
break;
case DIRECTION_DOWN:
snake[0][1] = snake[0][1] + SNAKEWIDTH;
break;
case DIRECTION_LEFT:
snake[0][0] = snake[0][0] - SNAKEWIDTH;
break;
case DIRECTION_RIGHT:
snake[0][0] = snake[0][0] + SNAKEWIDTH;
break;
}
}
/**
* 吃掉食物,自身增長
*/
private void eatFood(){
//判別蛇頭是否和食物重疊
if(snake[0][0] == foodX && snake[0][1] == foodY){
snakeNum++;
generateFood();
}
}
/**
* 產生食物
* 說明:食物的坐標必須位於屏幕內,且不能和蛇身重合
*/
private void generateFood(){
while(true){
foodX = Math.abs(random.nextInt() % (width - SNAKEWIDTH + 1))
/ SNAKEWIDTH * SNAKEWIDTH;
foodY = Math.abs(random.nextInt() % (height - SNAKEWIDTH + 1))
/ SNAKEWIDTH * SNAKEWIDTH;
boolean b = true;
for(int i = 0;i < snakeNum;i++){
if(foodX == snake[i][0] && snake[i][1] == foodY){
b = false;
break;
}
}
if(b){
break;
}
}
}
/**
* 判斷游戲是否結束
* 結束條件:
* 1、蛇頭超出邊界
* 2、蛇頭碰到自身
*/
private boolean isGameOver(){
//邊界判別
if(snake[0][0] < 0 || snake[0][0] > (width - SNAKEWIDTH) ||
snake[0][1] < 0 || snake[0][1] > (height - SNAKEWIDTH)){
return true;
}
//碰到自身
for(int i = 4;i < snakeNum;i++){
if(snake[0][0] == snake[i][0]
&& snake[0][1] == snake[i][1]){
return true;
}
}
return false;
}
/**
* 事件處理
*/
public void keyPressed(int keyCode){
int action = this.getGameAction(keyCode);
//改變方向
switch(action){
case UP:
if(direction != DIRECTION_DOWN){
direction = DIRECTION_UP;
}
break;
case DOWN:
if(direction != DIRECTION_UP){
direction = DIRECTION_DOWN;
}
break;
case LEFT:
if(direction != DIRECTION_RIGHT){
direction = DIRECTION_LEFT;
}
break;
case RIGHT:
if(direction != DIRECTION_LEFT){
direction = DIRECTION_RIGHT;
}
break;
case FIRE:
//暫停和繼續
isPaused = !isPaused;
break;
}
}
/**
* 線程方法
* 使用精確延時
*/
public void run(){
try{
while (isRun) {
//開始時間
long start = System.currentTimeMillis();
if(!isPaused){
//吃食物
eatFood();
//移動
move(direction);
//結束游戲
if(isGameOver()){
break;
}
//控制閃爍
b = !b;
}
//重新繪制
repaint();
long end = System.currentTimeMillis();
//延時
if(end - start < SLEEP_TIME){
Thread.sleep(SLEEP_TIME - (end - start));
}
}
}catch(Exception e){}
}
}