[转]J2ME贪吃蛇源代码——200行左右,包含详细注释

 

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

}



 

 

文章转自 Mailbomb的J2ME专栏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值