目的:编写一个贪吃蛇游戏,在控制台中操作。
思路:
1、贪吃蛇游戏中,需要蛇对象,食物对象和操作界面对象。
2、蛇对象中,包含蛇身对象(每个点),所以用容器存储蛇对象。
3、同理食物对象也需要容器存储。
4、操作界面由每个具体的点组成,所以需要一个生成点的类。
5、再将这些对象整合到一个控制游戏过程的对象中,实现游戏的过程。
代码:
生成操作界面的点类:
package cn.imcore.snake;
public class Point {//创建坐标点类
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Point other = (Point) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
生成食物的类:
package cn.imcore.snake;
import java.util.LinkedList;
import java.util.Random;
public class Food {//用链表集合存储食物,随机生成在游戏界面内
LinkedList f = new LinkedList();
Random r = new Random();
public Food() {
int x = r.nextInt(TestSnake.getrow()-2)+1;
int y = r.nextInt(TestSnake.getcol()-2)+1;
f.add(new Point(x,y));
}
}
生成蛇的类:
package cn.imcore.snake;
import java.util.LinkedList;
import java.util.Random;
public class Snake {
//用链表集合存储蛇,每节蛇身为一个对象(一个点对象)
LinkedList s = new LinkedList();
Random r = new Random();
public Snake() {//蛇随机生成在游戏界面的中间部位
int x = r.nextInt(TestSnake.getrow()/2)+TestSnake.getrow()/4;
int y = r.nextInt(TestSnake.getcol()/2)+TestSnake.getrow()/4;
for(int i=1; i<=3; i++) {//初始化蛇长3格
s.push(new Point(x, y-i));
}
}
}
控制游戏操作进程:
package cn.imcore.snake;
import java.util.LinkedList;
import java.util.Scanner;
public class TestSnake {
//设置游戏界面宽度和高度
private static int row = 16;
private static int col = 40;
public static int getrow(){
return row;
}
public static int getcol(){
return col;
}
//声明食物和蛇对象
private static LinkedList food = null;
private static LinkedList snake = null;
//主函数
public static void main(String[] args) {
startSnakeGame();
}
//启动贪吃蛇游戏
public static void startSnakeGame(){
snake = new Snake().s;//初始化蛇
prodeuceFood();//初始化食物
init();//初始化载入控制台界面
while(true){//键盘输入控制,开始游戏
char ch = control();//获取控制按钮,判断并返回操作结果
if(!(ch == 'A' || ch == 'W' || ch == 'D' || ch == 'S')){
continue;
}
else {
move(ch);//移动一格蛇,并判断是否吃到食物,返回新的游戏界面
//判断移动后,蛇头是否碰壁或碰到自身,是结束游戏还是继续游戏
if(deadOrContinue())
break;
}
}
}
//键盘输入控制键
@SuppressWarnings("resource")
public static char control(){
Scanner scanner = new Scanner(System.in);
String string = scanner.next().toUpperCase();
return string.charAt(0);
}
//移动蛇并做判断
public static void move(char m) {
Point snakeHead = snake.getLast();//获取链表集合内最后对象作为蛇头,,X代表行,Y代表列
switch(m) {
case 'A'://向左
if(snake.get(snake.size()-2).getY() == (snake.getLast().getY()-1))//防止蛇倒退走
break;
snake.addLast(new Point(snakeHead.getX(),snakeHead.getY()-1));//蛇头往前走,加一格
eatOrNot();//判断是否吃到,如果吃到,重新生成食物,蛇末尾不移除,如果没有吃到,移除蛇末
break;
case 'D'://向右
if(snake.get(snake.size()-2).getY() == (snake.getLast().getY()+1))
break;
snake.addLast(new Point(snakeHead.getX(),snakeHead.getY()+1));
eatOrNot();
break;
case 'W'://向上
if(snake.get(snake.size()-2).getX() == (snake.getLast().getX()-1))
break;
snake.addLast(new Point(snakeHead.getX()-1,snakeHead.getY()));
eatOrNot();
break;
case 'S'://向下
if(snake.get(snake.size()-2).getX() == (snake.getLast().getX()+1))
break;
snake.addLast(new Point(snakeHead.getX()+1,snakeHead.getY()));
eatOrNot();
break;
default:
break;
}
init();//形成新的游戏界面
}
//判断是否吃到食物
public static void eatOrNot(){//判断是否吃到食物,
if(snake.containsAll(food)){
prodeuceFood();//产生新食物
}else {
snake.pop();//去除蛇尾
}
}
//产生新食物
public static void prodeuceFood(){
food = new Food().f;
while (true) {//判断随机生成的食物是否与蛇重叠,如果重叠,重新生成
if(snake.containsAll(food))
food = new Food().f;
else
break;
}
}
//判断是否撞墙或者撞本身,如果是,游戏结束
public static boolean deadOrContinue(){
//判断是否撞墙
if(snake.getLast().getX() == 0 || snake.getLast().getX() == (row-1)
|| snake.getLast().getY() == 0 || snake.getLast().getY() == (col-1)){
System.out.println("游戏结束");
return true;
}
//判断是否撞本身:方式一:利用集合角标判断
if(snake.indexOf(snake.getLast()) != snake.size()-1){
System.out.println("游戏结束");
return true;
}
//判断是否撞本身:方式二:利用循环判断值
/*
for(int i =0; i < snake.size()-1; i++){//撞本身
if(snake.getLast().equals(snake.get(i))){
System.out.println("游戏结束");
return true;
}
}
*/
return false;
}
//显示游戏界面
public static void init() {
System.out.println("食物:" + food);//打印食物坐标
System.out.println("蛇身:" + snake);//打印蛇坐标
//遍历游戏界面,并打印相应的值
for(int m=0; m|