作者:[转载]  文章来源:http://www.alixixi.com/  更新时间:2006-3-19

  概述

  相信大家都玩过Nokia手机上的贪吃蛇游戏。在该游戏中,玩家操纵一条贪吃的蛇在迷宫里行走,贪吃蛇按玩家所按的方向键折行,蛇头吃到各种食物(比如大力丸)后,会有各种反应(比如蛇身变长),如果贪吃蛇碰上墙壁或者自身的话,就GameOver了(当然也可能是减去一条生命)。要实现该游戏其实并不麻烦,关键就是要找到一个合适的核心算法。本文就给出一个参考实现,你可以基于该demo做扩展。要说明的一点是:本文只演示最核心的算法,要实现一个完整的游戏,你还需要做很多的扩展,重构。

  实例代码

  该程序包括3个java文件。一个是SnakeMIDlet,另外2个分别是一个Canvas(SnakeCanvas)和一个代表贪吃蛇的类Snake

  SnakeMIDlet.java

  importjavax.microedition.lcdui.Display;

  importjavax.microedition.midlet.MIDlet;

  importjavax.microedition.midlet.MIDletStateChangeException;

  /**

  *@authorJagie

  */

  publicclassSnakeMIDletextendsMIDlet{

  protectedvoidstartApp()throwsMIDletStateChangeException{

  //TODOAuto-generatedmethodstub

  Display.getDisplay(this).setCurrent(newSnakeCanvas());

  }

  /*(non-Javadoc)

  *@seejavax.microedition.midlet.MIDlet#pauseApp()

  */

  protectedvoidpauseApp(){

  //TODOAuto-generatedmethodstub

  }

  /*(non-Javadoc)

  *@seejavax.microedition.midlet.MIDlet#destroyApp(boolean)

  */

  protectedvoiddestroyApp(booleanarg0)throwsMIDletStateChangeException{

  //TODOAuto-generatedmethodstub

  }

  }

  SnakeCanvas.java

  importjavax.microedition.lcdui.Canvas;

  importjavax.microedition.lcdui.Graphics;

  /**

  *@authorJagie

  *

  */

  publicclassSnakeCanvasextendsCanvasimplementsRunnable{

  Snakesnake=newSnake();

  SnakeCanvas(){

  snake.init();

  newThread(this).start();

  }

  protectedvoidpaint(Graphicsg){

  g.setColor(0);

  g.fillRect(0,0,this.getWidth(),this.getHeight());

  snake.paint(g);

  }

  /**

  *游戏主线程,驱动蛇移动

  */

  publicvoidrun(){

  while(true){

  snake.move();

  repaint();

  try{

  Thread.sleep(50);

  }catch(InterruptedExceptione){

  //TODOAuto-generatedcatchblock

  e.printStackTrace();

  }

  }

  }

  /**

  *按键相应,产生新蛇头

  */

  protectedvoidkeyPressed(intc){

  intga=this.getGameAction(c);

  switch(ga){

  caseCanvas.UP:

  snake.breakInto(1);

  break;

  caseCanvas.DOWN:

  snake.breakInto(3);

  break;

  caseCanvas.LEFT:

  snake.breakInto(4);

  break;

  caseCanvas.RIGHT:

  snake.breakInto(2);

  break;

  }

  }

  }

  Snake.java

  importjava.util.Vector;

  importjavax.microedition.lcdui.Graphics;

  /**

  *

  *@authorJagie

  *贪吃蛇

  */

  publicclassSnake{

  //蛇环节,每个环节为一个int[]sec

  //sec[0]:环节起点x,sec[1]:环节起点y,sec[2]:环节方向,sec[3]:环节长度

  Vectorsections=newVector();

  /**

  *初始化sections

  *开始的时候,整条蛇只有一段。

  *

  */

  publicvoidinit(){

  int[]head={10,10,2,50};

  sections.addElement(head);

  }

  /**

  *绘制

  *@paramg

  */

  publicsynchronizedvoidpaint(Graphicsg){

  if(sections.isEmpty()){

  return;

  }

  g.setColor(0,255,0);

  for(inti=0;i

  int[]sec=(int[])sections.elementAt(i);

  //sec[0]:起点x,sec[1]:起点y,sec[2]:方向,sec[3]:长度

  switch(sec[2]){

  case1:

  g.drawLine(sec[0],sec[1],sec[0],sec[1]-sec[3]);

  break;

  case2:

  g.drawLine(sec[0],sec[1],sec[0]+sec[3],sec[1]);

  break;

  case3:

  g.drawLine(sec[0],sec[1],sec[0],sec[1]+sec[3]);

  break;

  case4:

  g.drawLine(sec[0],sec[1],sec[0]-sec[3],sec[1]);

  break;

  }

  }

  }

  /**

  *

  *@authorJagie

  *

  *蛇的爬行。本质上是蛇头长度++,蛇尾长度--.同时移动蛇尾起点。如果蛇尾长度小于0,则去掉蛇尾。

  */

  publicsynchronizedvoidmove(){

  if(sections.isEmpty()){

  return;

  }

  //蛇尾

  int[]tail=(int[])sections.elementAt(sections.size()-1);

  //蛇头

  int[]head=(int[])sections.elementAt(0);

  //根据蛇尾环节的方向移动蛇尾。

  switch(tail[2]){

  case1:

  tail[1]--;

  break;

  case2:

  tail[0]++;

  break;

  case3:

  tail[1]++;

  break;

  case4:

  tail[0]--;

  break;

  }

  //蛇尾缩短

  tail[3]--;

  //蛇头增长

  head[3]++;

  //蛇尾<0,则去掉蛇尾

  if(tail[3]<=0){

  sections.removeElement(tail);

  }

  }

  /**

  *蛇分段

  *@paramdir新蛇头的方向

  */

  publicsynchronizedvoidbreakInto(intdir){

  if(sections.isEmpty()){

  return;

  }

  int[]head=(int[])sections.elementAt(0);

  //新蛇头方向和旧蛇头方向一致,则无反应。

  //TODO可以考虑加速。

  if(dir==head[2]){

  return;

  }

  //增加新蛇头

  int[]newhead=newint[4];

  //新蛇头的起始位置,与旧蛇头的运动方向有关。

  switch(head[2]){

  case1:

  newhead[0]=head[0];

  newhead[1]=head[1]-head[3];

  newhead[2]=dir;

  newhead[3]=0;

  //蛇头总是第一个元素

  sections.insertElementAt(newhead,0);

  break;

  case2:

  newhead[0]=head[0]+head[3];

  newhead[1]=head[1];

  newhead[2]=dir;

  newhead[3]=0;

  sections.insertElementAt(newhead,0);

  break;

  case3:

  newhead[0]=head[0];

  newhead[1]=head[1]+head[3];

  newhead[2]=dir;

  newhead[3]=0;

  sections.insertElementAt(newhead,0);

  break;

  case4:

  newhead[0]=head[0]-head[3];

  newhead[1]=head[1];

  newhead[2]=dir;

  newhead[3]=0;

  sections.insertElementAt(newhead,0);

  break;

  }

  }

  }

  小结

  本文给出了一个简单的贪吃蛇的例子,演示了贪吃蛇游戏核心的一种参考算法

  作者简介

  陈万飞,网名Jagie,培训师,爱好java技术.可通过chen_cwf@163.

网友评论
相关搜索
阿里西西Baidu.com搜索