Direction(int directionCode) {}
:每个方向对应一个值
public boolean compatibleWith(Direction d){}
:排除操作方向相反与移动方向相反的情况,防止游戏直接失败
代码:
enum Direction {
UP(0),
RIGHT(1),
DOWN(2),
LEFT(3);
private final int directionCode;
Direction(int directionCode) {
this.directionCode = directionCode;
}
//这里采用绝对值匹配
public boolean compatibleWith(Direction d){
if (Math.abs(this.directionCode-d.directionCode)==2) return false;
else return true;
}
}
Node(int x, int y){}
:坐标x与坐标y共同指向一个节点
代码:
class Node {
private final int x;
private final int y;
//成员变量x和y构成了一个节点
Node(int x, int y){
this.x = x;
this.y = y;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
public Node getHead(){}
:获取数组第一个元素
public Node addBody(Node newBody){}
:添加身体节点(蛇尾处)
public LinkedList
:获取身体长度(用于计算分数)
public Node move(Direction direction){}
:根据贪吃蛇移动的方法来变化它的坐标位置
代码:
class Snake {
//创建Node类型的身体数组,根据Node.java中的设置可知这是一个通过坐标组成的动态数组
//根据List的分类可知LinkedList链表数组适用于添加元素,所以这里利用创建body对象使用linkedList动态数组
//采用泛型对LinkedList中的元素进行限制
private LinkedList<Node> body = new LinkedList<Node>();
//返回数组第一个元素(蛇头)
public Node getHead(){
return body.getFirst();
}
//在数组末尾添加新元素(蛇尾)
public Node addBody(Node newBody){
body.addLast(newBody);
return newBody;
}
//获取蛇身体长度
public LinkedList<Node> getBody(){
return body;
}
//根据贪吃蛇移动的方法来变化它的坐标位置
public Node move(Direction direction){
Node newHead;
//newHead为body数组中的新增的第一个元素
//通过switch case为数组body中添加第一个元素newHead,同时移除最后一个元素节点
switch (direction){
//四种情况来设置newHead的位置
case UP:
newHead = new Node(body.getFirst().getX(),body.getFirst().getY()-1);
break;
case RIGHT:
newHead = new Node(body.getFirst().getX()+1,body.getFirst().getY());
break;
case DOWN:
newHead = new Node(body.getFirst().getX(),body.getFirst().getY()+1);
break;
case LEFT:
newHead = new Node(body.getFirst().getX()-1,body.getFirst().getY());
break;
default:
newHead = null;
}
body.add(0,newHead);//添加第一个节点
return body.removeLast();//返回删除最后一个节点
}
}
private int getRecord() {}
:获取记录分数
public int getScore(){}
:获取当前游戏分数
public int returnRecord(){}
:返回记录分数
public int increaseScore(){}
:记录增加的分数
public void changeRecord(int result) throws Exception{}
:通过文件读取处过去最高分数
private Node snakeAddBody(Node body){}
:当蛇增加一个身体节点后,返回增加节点后的蛇
private Snake initSnake(){}
:对蛇的长度与方向进行初始化
private Node createFood(){}
:随机生成食物
private Node snakeMove(){}
:判断蛇移动后游戏能否继续(根据Sanke.move,还需判断移动方向是否有效以及移动后游戏能否继续)
private boolean isHeadValid(){}
:判断头部接触的位置是否有效
private boolean headTouchBody(int headX, int headY){}
:判断头部是否接触身体
public boolean nextRound(){}
:根据头部位置是否有效来判断是否继续游戏
private boolean isHeadFood(){}
:判断头部是否接触食物
public void changeDirection(Direction newDirection){}
:判断方向改变是否有效(相反方向无效,根据Direction.compatibleWith()方法判断)
public Snake getSnake(){}
:获取Snake类的对象
public Node getFood(){}
:获取Node类的对象
代码:
class Grid {
//方格的覆盖可以用一个boolean类型的二维数组来表示
public final boolean status[][];
//固定方格的宽与长
private final int width;
private final int height;
private int score = 0;
private int record;
private Snake snake;
private Node food;
//蛇的初始方向默认向左;
private Direction snakeDirection = Direction.LEFT;
Grid(int width, int height) throws Exception {
this.height = height;
this.width = width;
//这里采用稀疏数组,用f=便于直接用for循环一次性记录整个网格
//由于网格只有被覆盖与未被覆盖的情况,所以使用boolean类型
status = new boolean[width][height];//蛇占据的地方为true
initSnake();
createFood();
this.record = getRecord();
}
private int getRecord() throws Exception {
//获取记录分数,须在指定路径下创建文件夹
BufferedReader recordFile = new BufferedReader(new FileReader("src/snake/scoresRecord.txt"));
String a = recordFile.readLine();
this.record = Integer.parseInt(a.trim());
recordFile.close();
return record;
}
public int getScore(){
return score;
}
public int returnRecord(){
return record;
}
public int increaseScore(){
score++;
return score;
}
public void changeRecord(int result) throws Exception{
//通过文件记录分数
FileWriter fw = new FileWriter("src/snake/scoresRecord.txt",false);
BufferedWriter recordFile = new BufferedWriter(fw);
recordFile.write(String.valueOf(result));
fw.flush();
recordFile.close();
}
private Node snakeAddBody(Node body){
//当蛇增加一个身体节点后,返回增加节点后的蛇
status[body.getX()][body.getY()] = true;
snake.addBody(body);
return body;
}
private Snake initSnake(){
// 1.设置Snake的Body
// 2.更新棋盘覆盖状态
this.snake = new Snake();
//蛇初始为横着的状态,长度为width的三分之一
int headX = (int)(width/6*Math.random()+width/3);
int headY = (int)(height*Math.random());
while(headY <= 0|| headY>height-2){
headY = (int)(height*Math.random());
}
Node head = new Node(headX,headY);
snakeAddBody(head);
for (int i=1; i<(int)(width/3); i++){
headX++;
snakeAddBody(new Node(headX,headY));
}
return snake;
}
private Node createFood(){
//随机创建食物,生成食物的X坐标和Y坐标。使用Random类来生成随机数。
//生成的食物X坐标和Y坐标不能超过棋盘大小,食物的位置不能和贪吃蛇的位置重叠
int foodX = (int)(width*Math.random());
int foodY = (int)(height*Math.random());
while(status[foodX][foodY] || foodX<=0 || foodX>width-2 || foodY <= 0 || foodY>height-2){
foodX = (int)(width*Math.random());
foodY = (int)(height*Math.random());
}
this.food = new Node(foodX,foodY);
return food;
}
private Node snakeMove(){
//根据Sanke.move方法判断移动方向是否有效以及移动后游戏能否继续
Node tail = snake.move(snakeDirection);
status[snake.getHead().getX()][snake.getHead().getY()] = true;
status[tail.getX()][tail.getY()] = false;
return tail;
}
public boolean nextRound(){
//根据头部位置是否有效来判断是否继续游戏
//移动后游戏继续返回true,否则返回false
Node tail = snakeMove();
if(isHeadValid()){
if (isHeadFood()) {
snake.addBody(tail);
status[tail.getX()][tail.getY()] = true;
createFood();
increaseScore();
}
return true;
}
else{
return false;
}
}
private boolean isHeadValid(){
//判断头部接触的位置是否有效
Node head = snake.getHead();
int headX = head.getX();
int headY = head.getY();
if (headX <= 0 || headX >= width-1 || headY <= 0 || headY >= height-1 || headTouchBody(headX,headY)){
return false;
}
else{
return true;
}
}
private boolean headTouchBody(int headX, int headY){
//判断头部是否接触身体
LinkedList<Node> a = snake.getBody();
for (int i=1; i<a.size(); i++){
if (headX == a.get(i).getX() && headY == a.get(i).getY()){
return true;
}
}
return false;
}
private boolean isHeadFood(){
//判断头部是否接触食物
Node head = snake.getHead();
if (head.getX() == food.getX() && head.getY() == food.getY()){
return true;
}
else{
return false;
}
}
public void changeDirection(Direction newDirection){
//判断方向改变是否有效(相反方向无效,根据Direction.compatibleWith()方法判断)
if (snakeDirection.compatibleWith(newDirection)){
snakeDirection = newDirection;
}
}
//引入snake对象
public Snake getSnake(){
return this.snake;
}
//引入食物位置
public Node getFood(){
return this.food;
}
}
后续会继续更新,把剩下的代码补齐