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;
/**离屏画布*/
Graphics offG;
/**离屏画笔*/
Image offImage;
/*移动方向*/
/**向上*/
final int DIRECTION_UP = 0;
/**向下*/
final int DIRECTION_DOWN = 1;
/**向左*/
final int DIRECTION_LEFT = 2;
/**向右*/
final int DIRECTION_RIGHT = 3;
/**游戏区域宽度*/
int width;
/**游戏区域高度*/
int height;
/**蛇身单元宽度*/
private final byte SNAKEWIDTH = 8;
/**是否处于暂停状态,true代表暂停*/
boolean isPaused = false;
/**是否处于运行状态,true代表运行*/
boolean isRun = true;
/**时间间隔*/
private final int SLEEP_TIME = 300;
/**食物的X坐标*/
int foodX;
/**食物的Y坐标*/
int foodY;
/**食物的闪烁控制*/
boolean b = true;
/**列数,行数*/
int col,row;
Random random = new Random();
public boolean gameLost;
public SnakeCanvas() {
gameLost = false;
//初始化节点数量
snakeNum = 7;
//初始化节点数据
for(int i = 0;i < snakeNum;i++){
snake[i][0] = SNAKEWIDTH*7 - SNAKEWIDTH * i;
snake[i][1] = SNAKEWIDTH *5;
}
//初始化移动方向
direction = DIRECTION_RIGHT;
//初始化食物坐标
foodX = SNAKEWIDTH*7;
foodY = SNAKEWIDTH*7;
width = this.getWidth();
height = this.getHeight()-16;
col = width/8;
row = height/8;
offImage = Image.createImage(this.getWidth(), this.getHeight());
offG = offImage.getGraphics();
//启动线程
new Thread(this).start();
}
protected void paint(Graphics g) {
drawBg(offG);
//绘制蛇身
for(int i = 0;i < snakeNum;i++){
offG.fillRect(snake[i][0],snake[i][1],SNAKEWIDTH,SNAKEWIDTH);
}
//绘制食物
if(b){
offG.fillRect(foodX,foodY,SNAKEWIDTH,SNAKEWIDTH);
}
offG.drawString("开始 退出", 0, height, 0);
if(gameLost){
offG.drawString("游戏失败", 60, height, 0);
}
g.drawImage(offImage, 0, 0, 0);
}
//画背景
private void drawBg(Graphics g){
//清屏
g.setColor(0xffffff);
g.fillRect(0,0,width,height);
g.setColor(0);
//画单元格子
for(int i=0; i<row+1; i++){
g.drawLine(0, i*SNAKEWIDTH, width, i*SNAKEWIDTH);
}
for(int j=0; j<col; j++){
g.drawLine(j*SNAKEWIDTH, 0, j*SNAKEWIDTH, height);
}
}
private synchronized 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:
if(snake[0][1] < height- SNAKEWIDTH){
snake[0][1] = snake[0][1] + SNAKEWIDTH;
}else{
snake[0][1] = snake[0][1] +1;
}
break;
case DIRECTION_LEFT:
snake[0][0] = snake[0][0] - SNAKEWIDTH;
break;
case DIRECTION_RIGHT:
if(snake[0][0] < width- SNAKEWIDTH){
snake[0][0] = snake[0][0] + SNAKEWIDTH;
}else{
snake[0][0] = snake[0][0] +1;
}
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)){
gameLost = true;
return true;
}
//碰到自身
for(int i = 4;i < snakeNum;i++){
if(snake[0][0] == snake[i][0]&& snake[0][1] == snake[i][1]){
gameLost = true;
return true;
}
}
return false;
}
/**
* 事件处理
*/
public void keyPressed(int keyCode){
int action = this.getGameAction(keyCode);
if(keyCode == -6){//重新开始
SnakeMIDlet.midlet.gameStart();
}else if(keyCode == -7){
SnakeMIDlet.midlet.gameExit();
}
//改变方向
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()){
repaint();
break;
}
//控制闪烁
b = !b;
}
//重新绘制
repaint();
long end = System.currentTimeMillis();
//延时
if(end - start < SLEEP_TIME){
Thread.sleep(SLEEP_TIME - (end - start));
}
}
}catch(Exception e){}
}
}
j2me 贪吃蛇源码
需积分: 6 139 浏览量
2010-04-14
17:05:52
上传
评论
收藏 3KB RAR 举报
aoqilinjian
- 粉丝: 6
- 资源: 9