/** 蛇前进的方向,向上 */ public static final int DIR_UP = -1; /** 蛇前进的方向,向下 */ public static final int DIR_DOWN = 1; /** 蛇前进的方向,向左 */ public static final int DIR_LEFT = -2; /** 蛇前进的方向,想右 */ public static final int DIR_RIGHT = 2; /** * 改变蛇的运动方向 * @param direction 蛇的新的运动方向 */ public void changeDirection(int direction){ if(this.direction + direction != 0){ this.direction = direction; } }我想各位聪明的看官已经很清楚了,咱们作了什么,这里运用了一点技巧,咱们把相反方向上的两个方向的值设置为一正一负,那么咱们的问题就解决了,也很优雅。嗯嗯,好了,再次运行你的程序,就算你把键盘戳烂了都不会出现那种状况了,呵呵。
解决了一点小问题,咱们继续咱们的贪吃蛇。咱们的蛇到目前为止已经基本上OK了,接下来咱们将要开始对蛇的食物进行编码,咱们有吃的啦!!固然,咱们新建一个叫Food的类,放在com.gulang.snake.entity包下面。下面就是咱们编写的Food类,请看代码:
java
package com.gulang.snake.entity; import java.awt.Color; import java.awt.Graphics; import java.util.Random; import com.gulang.snake.view.GameView; /** * 食物对象 * @author jiladeyouxiang@qq.com * */ public class Food { /** 食物的大小,咱们这里是和蛇的一个身体节点同样大 */ public static final int FOOD_SIZE = Snake.BODY_SIZE; /** 食物的位置,横坐标 */ private int x; /** 食物的位置,纵坐标 */ private int y; /** * 构造一个食物对象,而且设置食物出现的位置在游戏的窗口上的任何一个有效的地方 * 1.不能出如今窗口外; * 2.不能出如今有蛇的位置; * 3.不能出如今有石块的地方 * * @param 游戏中的蛇的对象 */ public Food(Snake snake){ //咱们先将咱们的游戏窗口网格化,并计算出每一行有多少个单元格,每一列有多少个单元格 int cellsInRow = GameView.WINDOW_WIDTH / Snake.BODY_SIZE; int cellsInCol = GameView.WINDOW_HEIGHT / Snake.BODY_SIZE; //咱们用随机数类来产生咱们的食物的横坐标和纵坐标,而且保证食物的坐标不产生在蛇的身体上 Random r = new Random(); do{ createXY(r, cellsInRow, cellsInCol); } while (isInSnakeBody(snake)); } /** * 生成新的食物的坐标 * @param r 随机数对象 * @param cellsInRow 一行中的单元格个数 * @param cellsInCol 一列中的单元格个数 */ private void createXY(Random r, int cellsInRow, int cellsInCol){ x = r.nextInt(cellsInRow) * Snake.BODY_SIZE; y = r.nextInt(cellsInCol) * Snake.BODY_SIZE; } /** * 判断当前食物的位置是否在蛇的身体上 * @param snake 蛇 * @return 若是当前的食物在蛇的身体上则返回true,不然返回false */ public boolean isInSnakeBody(Snake snake){ for(Snake.Body body : snake.getSnakeBody()){ if(this.x == body.getX() && this.y == body.getY()){ return true; } } return false; } /** * 将食物绘制出来 * @param g */ public void drawMe(Graphics g){ //得到画笔原来的颜色 Color c = g.getColor(); //将画笔的颜色设置为绿色 g.setColor(Color.GREEN); //绘制一个3D的绿色方块做为食物 g.fill3DRect(x, y, FOOD_SIZE, FOOD_SIZE, true); //将画笔的颜色还原回去 g.setColor(c); } }咱们如今已经有了Snake类的经验,所以我想你们对于该类的理解应该不存在什么有困难的地方。固然,有几点关于游戏的细节仍是须要注意的,好比咱们Food的构造方法,咱们食物的产生地必须知足几个条件,这些我都写在注释上了,你们应该也看到了。接着呢,为了看到效果,咱们只须要在GameView中添加关于Food类的代码就能够了,我想可以看到这里的你也应该没有什么问题了,固然,惯例孤狼仍是贴一下代码,请看:
/** * 绘制界面的方法 */ @Override public void paint(Graphics g) { //将窗口清空 g.clearRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); //绘制蛇的对象 snake.drawMe(g); //绘制食物 food.drawMe(g); }到这里呢,还有一点小问题,是咱们以前在写Snake类时留下来的,你们回想一下咱们在写Snake类时设置的蛇的边长是30,可是咱们的游戏的窗口的边长是800,这在咱们将窗口网格化的时候就会出现问题,致使咱们蛇的位置和食物的位置对不齐,所以呢咱们首先将蛇的身体的大小改成20,而后再将蛇的初始化位置修正。咱们原来是让蛇在窗口的正中央,可是网格化之后咱们须要的实际上是在最中间的那一个,所以咱们修改蛇的构造方法,看代码:
/** * 初始化一条蛇 */ public Snake(){ //初始化蛇最开始前进的方向为向右 direction = DIR_RIGHT; //咱们将蛇的第一节身体初始化在游戏窗口的中央 int cellsInRow = GameView.WINDOW_WIDTH / BODY_SIZE; int cellsInCol = GameView.WINDOW_HEIGHT / BODY_SIZE; int startX = cellsInRow / 2 * BODY_SIZE; int startY = cellsInCol / 2 * BODY_SIZE; //初始化蛇的身体,即向body链表中添加数据,咱们初始化蛇的初始节点为3个 for(int i = 0; i < 3; i++){ //逐个的计算出蛇的每个节点的位置 Body body = new Body(startX - i * BODY_SIZE, startY); snakeBody.add(body); } }那么到这里呢,咱们的这个小项目就作完了,运行一下看看吧,是否是感受已经有一点贪吃蛇游戏的雏形了,仍是小有成就感的吧,呵呵。咱们如今能够控制咱们的蛇去吃食物了,可是遗憾的是蛇如今通过食物的时候还不能吃掉食物,这个咱们将在下一次的项目中来完成这个功能。那今天就到这里吧,晚安啦,各位,但愿天亮之后我还有机会完成后面的博文,呵呵,芥末日快乐啦。