黑马程序员技术交流社区

标题: 分享游戏心得——贪吃蛇的java代码分析(二) [打印本页]

作者: EnterEn_RllVn    时间: 2016-6-9 18:27
标题: 分享游戏心得——贪吃蛇的java代码分析(二)
本帖最后由 EnterEn_RllVn 于 2016-6-9 18:46 编辑

     接下来是我们进行游戏中至关重要的一点,就是对蛇的移动进行控制。我们使用“wsad”或者键盘上的“上下左右”来控制蛇身的移动变化。这其中的原理想必很多人都能马上想到:监听器。这里我们要设置监听器的对象不再是一个按钮,一个标签,而是整个面板。我们要对整个面板增加一个键盘监听器,用来监听自己在键盘上的动作。这里我们统一一下,用"↑↓←→”来控制方向。当我们使用键盘捕捉到相应的动作后,该如何继续呢?该如何编写事件的处理?我们来翻阅一下API。查看API中的KeyListener,我们可以查到KeyEvent,他有静态的常量用来表示键盘上相应的点触。VK_UP代表上箭头,VK_DOWN代表下箭头,VK_LEFT代表左箭头,VK_RIGHT代表右箭头。我们马上可以联想到:通过getKeyCode方法获取到键盘事件,和四个常量进行比较,如果符合,就可以按照对应的方向调用方法,来移动蛇身。我们可以定义一个Move()方法,并且定义一个变量direction代表方向,通过对direction不同的赋值传递给Move(),来对蛇身产生不同的移动效果。接下来贴代码:
  1. public mainMap() {
  2.         snake.add(new snakeNode(width/2,length/2,Color.RED);
  3.         snake.add(new snakeNode(width/2,length/2+1,Color.BLUE);
  4.         snake.add(new snakeNode(width/2,length/2+2,Color.GREY);
  5.         Length = snake.size();
  6.         createNode();
  7.         this.addKeyListener(new KeyAdaper() {
  8.                 public void KeyPressed(KeyEvent e) {
  9.                         int direction = 0;
  10.                         switch(e.getKeyCode()) {
  11.                                 case KeyEvent.VK_UP:
  12.                                         direction = 1;
  13.                                         break;
  14.                                 case KeyEvent.VK_DOWN:
  15.                                         direction = -1;
  16.                                         break;
  17.                                 case KeyEvent.VK_LEFT:
  18.                                         direction = 2;
  19.                                         break;
  20.                                 case KeyEvent.VK_RIGHT:
  21.                                         direction = -2;
  22.                                         break;
  23.                                 default:
  24.                                         break;
  25.                                 }
  26.                         Move(direction);
  27.                         }
  28.                 });
  29.         }
复制代码

//通过按下不同的方向键,我们得到了不同的direction变量,接下来我们定义一个Move()方法,传递direction变量来控制坐标的移动,从而得到蛇身变化的效果。


  1.         public void Move(int direction) {
  2.                 int firstX = snake.get(0).getX();
  3.                 int firstY = snake.get(0).getY();
  4.                 switch(direction) {
  5.                         case 1:
  6.                                 firstY--;
  7.                                 break;
  8.                         case -1:
  9.                                 firstY++;
  10.                                 break;
  11.                         case 2:
  12.                                 firstX--;
  13.                                 break;
  14.                         case -2:
  15.                                 firstX++;
  16.                                 break;
  17.                         default:
  18.                                 break;
  19.                         }
  20.                 for(int x = 0; x < Length; x++) {
  21.                         if(snake.get(x).getX()==firstX&&snake.get(x).getY()==firstY) {
  22.                         Dead("不好意思,您碰到自己啦~~~~!!!!");
  23.                         }
  24.                 }//这个方法遍历蛇身集合中的每一个元素,拿出X轴和Y轴的值进行比较,来保证蛇头的第一个点没有触碰到蛇身的其他点。如果碰到了,就调用Dead()方法结束游戏,Dead()方法随后定义

  25.                 if(firstX < 0 || firstX > width - 1 || firstY < 0 || firstY > length -1) {
  26.                 Dead("不好意思,您撞墙啦");
  27.                 }//很简单,判断蛇头的坐标有没有超出界限
  28.                
  29.                 for(int x = Length - 1; x >0; x--) {
  30.                         snake.get(x).setX(snake.get(x-1).getX());
  31.                         snake.get(x).setY(snake.get(x-1).getY());
  32.                 }
  33.                 snake.get(0).setX(firstX);
  34.                 snake.get(0).setY(firstY);
  35.                 }//这段代码从后往前遍历集合,把最后一个集合的X轴和Y轴赋值为前一个元素的X轴和Y轴,把移动后的firstX和firstY坐标赋值给第一个元素,那么蛇身的整体位置就进行了变化,也就可以达到蛇身移动的效果了。
复制代码

通过以上代码,我们已经初步搭建了贪吃蛇的基本逻辑框架。我们造出了蛇身,设置了按键后的蛇身移动的规律,也设置了蛇移动的范围。我们先给出总览的代码,这样有助于查漏补缺:



  1. public class mainMap extends JPanel {
  2.         private final int width = 20;
  3.         private final int length = 30;
  4.         private final int unit = 20;
  5.         private ArrayList<snakeNode> snake = new ArrayList<>();
  6.         private snakeNode newNode = new snakeNode(0,0,Color.WHITE);
  7.         private int Length;
  8.         
  9.         public mainMap() {//这是构造方法
  10.         snake.add(new snakeNode(width/2,length/2,Color.RED);
  11.         snake.add(new snakeNode(width/2,length/2+1,Color.BLUE);
  12.         snake.add(new snakeNode(width/2,length/2+2,Color.GREY);
  13.         Length = snake.size();
  14.         
  15.         createNode();//这是创造随机点的方法
  16.         
  17.         this.addKeyListener(new KeyAdaper() {//这是设置键盘事件的方法
  18.                 public void KeyPressed(KeyEvent e) {
  19.                         int direction = 0;
  20.                         switch(e.getKeyCode()) {
  21.                                 case KeyEvent.VK_UP:
  22.                                         direction = 1;
  23.                                         break;
  24.                                 case KeyEvent.VK_DOWN:
  25.                                         direction = -1;
  26.                                         break;
  27.                                 case KeyEvent.VK_LEFT:
  28.                                         direction = 2;
  29.                                         break;
  30.                                 case KeyEvent.VK_RIGHT:
  31.                                         direction = -2;
  32.                                         break;
  33.                                 default:
  34.                                         break;
  35.                                 }
  36.                         Move(direction);
  37.                         }
  38.                 });
  39.         }
  40.         }
  41.         public void Move(int direction) {//这是移动蛇身的方法
  42.                 int firstX = snake.get(0).getX();
  43.                 int firstY = snake.get(0).getY();
  44.                 switch(direction) {
  45.                         case 1:
  46.                                 firstY--;
  47.                                 break;
  48.                         case -1:
  49.                                 firstY++;
  50.                                 break;
  51.                         case 2:
  52.                                 firstX--;
  53.                                 break;
  54.                         case -2:
  55.                                 firstX++;
  56.                                 break;
  57.                         default:
  58.                                 break;
  59.                         }
  60.                 for(int x = 0; x < Length; x++) {
  61.                                                         if(snake.get(x).getX()==firstX&&snake.get(x).getY()==firstY) {
  62.                         Dead("不好意思,您碰到自己啦~~~~!!!!");
  63.                         }
  64.                 }

  65.                 if(firstX < 0 || firstX > width - 1 || firstY < 0 || firstY > length -1) {
  66.                 Dead("不好意思,您撞墙啦");
  67.                 }
  68.                 for(int x = Length - 1; x >0; x--) {
  69.                         snake.get(x).setX(snake.get(x-1).getX());
  70.                         snake.get(x).setY(snake.get(x-1).getY());
  71.                 }
  72.                 snake.get(0).setX(firstX);
  73.                 snake.get(0).setY(firstY);
  74.                 }

  75.         public void createNode() {//这是创造随机点的方法
  76.         int newX = 0;
  77.         int newY = 0;
  78.         boolean flag = true;
  79.         while(flag){
  80.         X = new Random().nextInt(width);
  81.         Y = new Random().nextInt(length);
  82.         for(int x = 0; x < Length; x++) {
  83.                 if(snake.get(x).getX() == newX && snake.get(x).getY() == newY) {
  84.                 flag = true;
  85.                 break;
  86.                 }
  87.                 flag = false;
  88.         }
  89. }
  90.         Color color = new Color(new Random().nextInt(255),new Random().nextInt(255),new Random().nextInt(255));
  91.         newNode.setX(newX);
  92.         newNode.setY(newY);
  93.         newNode.setColor(color);
  94.         }
复制代码



以上就是我们共同完成的步骤,如果全部实现并且加以理解,那么其实整个贪吃蛇的整体思路基本已经是掌握了。但这并没有结束,我们还有许多的细节问题需要完成。我将在下一节中继续来完成剩下的部分,包括蛇的定时移动,吃掉点的方法,已经画出蛇的样子。




作者: Hellow_word    时间: 2016-6-9 19:47
厉害 可以




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2