/** 蛇前进的方向,向上 */ 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类,请看代码:
package com.gulang.snake.entity; import java.awt.Color; import java.awt.Graphics; import java.util.Random; import com.gulang.snake.view.GameView; /** * 食物对象 * @author [email protected] * */ 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); } }那么到这里呢,我们的这个小项目就做完了,运行一下看看吧,是不是感觉已经有一点贪吃蛇游戏的雏形了,还是小有成就感的吧,呵呵。我们现在可以控制我们的蛇去吃食物了,但是遗憾的是蛇现在经过食物的时候还不能吃掉食物,这个我们将在下一次的项目中来完成这个功能。那今天就到这里吧,晚安啦,各位,希望天亮以后我还有机会完成后面的博文,呵呵,芥末日快乐啦。