www.pudn.com > SnakeMIDlet.rar > SnakeMIDlet.java


//文件名:SnakeMIDlet .java 
 
 
 
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   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){} 
    } 
}