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

    }

}