开发经验谈:贪吃蛇游戏的MIDP实现核心

877685315

877685315

2016-02-19 13:40

get新技能是需要付出行动的,即使看得再多也还是要动手试一试。今天图老师小编跟大家分享的是开发经验谈:贪吃蛇游戏的MIDP实现核心,一起来学习了解下吧!
相信大家都玩过Nokia手机上的贪吃蛇游戏。在该游戏中,玩家操纵一条贪吃的蛇在迷宫里行走,贪吃蛇按玩家所按的方向键折行,蛇头吃到各种食物(比如大力丸)后,会有各种反应(比如蛇身变长),假如贪吃蛇碰上墙壁或者自身的话,就GameOver了(当然也可能是减去一条生命)。
  
  要实现该游戏其实并不麻烦,要害就是要找到一个合适的核心算法。本文就给出一个参考实现,你可以基于该demo做扩展。要说明的一点是:本文只演示最核心的算法,要实现一个完整的游戏,你还需要做很多的扩展,重构。
  
  实例代码
  
  该程序包括3个Java文件。一个是SnakeMIDlet,另外2个分别是一个Canvas(SnakeCanvas)和一个代表贪吃蛇的类Snake: SnakeMIDlet.java
  import javax.microedition.lcdui.Display;
  import javax.microedition.midlet.MIDlet;
  import javax.microedition.midlet.
  MIDletStateChangeException;
  
  /**
  * @author Jagie
  */
  public class SnakeMIDlet extends MIDlet
  {
  
  protected void startApp()
  throws MIDletStateChangeException
  {
  // TODO Auto-generated method stub
  Display.getDisplay(this)
  .setCurrent(new SnakeCanvas());
  
  }
  
  /* (non-Javadoc)
  * @see javax.microedition
  .midlet.MIDlet#pauseApp()
  */
  protected void pauseApp()
  {
  // TODO Auto-generated method stub
  
  }
  
  /* (non-Javadoc)
  * @see javax.microedition
  .midlet.MIDlet#destroyApp(boolean)
  */
  protected void destroyApp(boolean arg0)
  throws MIDletStateChangeException
  {
  // TODO Auto-generated method stub
  
  }
  
  }
  
  SnakeCanvas.java
  
  import javax.microedition.lcdui.Canvas;
  import javax.microedition.lcdui.Graphics;
  
  /**
  * @author Jagie
  *
  */
  public class SnakeCanvas extends
  Canvas implements Runnable
  {
  
  Snake snake=new Snake();
  SnakeCanvas(){
  snake.init();
  new Thread(this).start();
  }
  
  protected void paint(Graphics g)
  {
  
  g.setColor(0);
  g.fillRect(0,0,this.getWidth(),
  this.getHeight());
  
  snake.paint(g);
  
  }
  
  /**
  * 游戏主线程,驱动蛇移动
  */
  
  public void run()
  {
  while(true){
  
  snake.move();
  repaint();
  
  try
  {
  Thread.sleep(50);
  } catch (InterruptedException e)
  {
  // TODO Auto-generated
  catch block
  e.printStackTrace();
  }
  }
  }
  
  /**
  * 按键相应,产生新蛇头
  */
  protected void keyPressed(int c)
  {
  int ga=this.getGameAction(c);
  
  switch (ga)
  {
  case Canvas.UP:
  snake.breakInto(1);
  break;
  
  case Canvas.DOWN:
  snake.breakInto(3);
  break;
  case Canvas.LEFT:
  snake.breakInto(4);
  break;
  case Canvas.RIGHT:
  snake.breakInto(2);
  break;
  }
  }
  }
  
  Snake.java
  
  import java.util.Vector;
  
  import javax.microedition.lcdui.Graphics;
  
  /**
  *
  * @author Jagie
  * 贪吃蛇
  */
  public class Snake
  {
  //蛇环节,每个环节为一个int[] sec
  //sec[0]:环节起点x,sec[1]:
  环节起点y,sec[2]:环节方向,sec[3]:
  环节长度
  Vector sections = new Vector();
  
  /**
  * 初始化sections
  * 开始的时候,整条蛇只有一段。
  *
  */
  public void init()
  {
  int[] head =
  { 10, 10, 2, 50 };
  sections.addElement(head);
  }
  
  /**
  * 绘制
  * @param g
  */
  public synchronized
  void paint(Graphics g)
  {
  if (sections.isEmpty())
  {
  return;
  }
  g.setColor(0, 255, 0);
  for (int i = 0; i sections.size();
  i++)
  {
  int[] sec = (int[])
  sections.elementAt(i);
  //sec[0]:起点x,sec[1]:
  起点y,sec[2]:方向,sec[3]:
  长度
  switch (sec[2]) {
  case 1:
  g.drawLine(sec[0], sec[1],
  sec[0], sec[1] - sec[3]);
  break;
  case 2:
  g.drawLine(sec[0], sec[1],
  sec[0] + sec[3], sec[1]);
  break;
  case 3:
  g.drawLine(sec[0], sec[1],
  sec[0], sec[1] + sec[3]);
  break;
  case 4:
  g.drawLine(sec[0], sec[1],
  sec[0] - sec[3], sec[1]);
  break;
  }
  
  }
  }
  
  /**
  *
  * @author Jagie
  *
  * 蛇的爬行。本质上是蛇头长度++,蛇尾长度--。
  同时移动蛇尾起点。假如蛇尾长度小于0,则去掉蛇尾。
  */
  public synchronized void move()
  {
  if (sections.isEmpty())
  {
  return;
  }
  //蛇尾
  int[] tail = (int[])
  sections.elementAt
  (sections.size() - 1);
  //蛇头
  int[] head = (int[])
  sections.elementAt(0);
  //根据蛇尾环节的方向移动蛇尾。
  switch (tail[2])
  {
  case 1:
  tail[1]--;
  break;
  case 2:
  tail[0]++;
  break;
  case 3:
  tail[1]++;
  break;
  case 4:
  tail[0]--;
  break;
  }
  //蛇尾缩短
  tail[3]--;
  //蛇头增长
  head[3]++;
  //蛇尾0,则去掉蛇尾
  if (tail[3] = 0)
  {
  sections.removeElement(tail);
  }
  }
  
  /**
  * 蛇分段
  * @param dir 新蛇头的方向
  */
  
  public synchronized void
  breakInto(int dir)
  {
  if (sections.isEmpty())
  {
  return;
  }
  int[] head = (int[])
  sections.elementAt(0);
  //新蛇头方向和旧蛇头方向一致,
  则无反应。
  //TODO 可以考虑加速。
  if (dir == head[2])
  {
  return;
  }
  //增加新蛇头
  int[] newhead=new int[4];
  //新蛇头的起始位置,
  与旧蛇头的运动方向有关。
  switch (head[2])
  {
  case 1:
  newhead[0]=head[0];
  newhead[1]=head[1]-head[3];
  newhead[2]=dir;
  newhead[3]=0;
  //蛇头总是第一个元素
  sections.insertElementAt(newhead, 0);
  break;
  case 2:
  newhead[0]=head[0]+head[3];
  newhead[1]=head[1];
  newhead[2]=dir;
  newhead[3]=0;
  sections.insertElementAt(newhead, 0);
  break;
  case 3:
  newhead[0]=head[0];
  newhead[1]=head[1]+head[3];
  newhead[2]=dir;
  newhead[3]=0;
  sections.insertElementAt(newhead, 0);
  break;
  case 4:
  newhead[0]=head[0]-head[3];
  newhead[1]=head[1];
  newhead[2]=dir;
  newhead[3]=0;
  sections.insertElementAt(newhead, 0);
  break;
  }
  
  }
  
  }
展开更多 50%)
分享

猜你喜欢

开发经验谈:贪吃蛇游戏的MIDP实现核心

编程语言 网络编程
开发经验谈:贪吃蛇游戏的MIDP实现核心

利用C++实现的贪吃蛇游戏

编程语言 网络编程
利用C++实现的贪吃蛇游戏

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

JAVASCRIPT 贪吃蛇

Web开发
JAVASCRIPT 贪吃蛇

HTML5 贪吃蛇游戏实现思路及源代码

Web开发
HTML5 贪吃蛇游戏实现思路及源代码

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

html5贪吃蛇游戏使用63行代码完美实现

Web开发
html5贪吃蛇游戏使用63行代码完美实现

贪吃蛇大作战是单机吗 贪吃蛇大作战是单机游戏吗

贪吃蛇大作战
贪吃蛇大作战是单机吗 贪吃蛇大作战是单机游戏吗

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

无法使用桌面快捷方式?高手帮你忙

无法使用桌面快捷方式?高手帮你忙

让Win8.1游戏界面全屏的小攻略

让Win8.1游戏界面全屏的小攻略
下拉加载更多内容 ↓