开发背景作为一个经典的游戏,贪吃蛇设计简单,实用和娱乐性高,是90后童年的美好回忆。
对于贪吃蛇传统的玩法,大家众所周知,即:玩家通过控制游戏手柄上下左右四个方向控制蛇的前进方向,每当吃到一个东西就会增加相应的分数,蛇的身子会越吃越长,蛇身越长游戏的难度就越大,不能咬到自己的身体,也不能碰到墙壁,积累到一定分数就可以通过此关,进入到下一关。
需求分析该次小游戏程序设计包含二维数组、方向键操作及图形化函数等方面知识。
具体需求概要如下:1、游戏界面初始化,显示背景区域和活动区域2、按方向键上下左右进行游戏的控制3、当蛇头吃到食物时,蛇身长度加一,分数增加4、当蛇头撞墙或者碰到自身时,游戏结束,显示“GAME OVER”和累加得分里面存在的事物:地图、蛇、食物游戏规则:1.蛇初始化时是3个节点,一开始蛇是出现在地图中间位置的2.蛇吃到食物会长一节3.蛇咬到自己会死4.蛇撞墙会死5.食物随机生成的,食物不长在背景上,不长在蛇身上。
使用技术本次课程使用JAVA来完成游戏的设计,使用二维数组存储背景信息,使用List存储蛇身信息,使用Swing完成图形界面化。
功能开发概要设计1、初始化模块:屏幕初始化,屏幕初始化用于显示游戏信息“贪吃蛇”。
2、游戏界面模块:设计边框和贪吃蛇活动区域3、游戏运行模块:运用函数控制蛇长及吃食物关系,使用方向键控制方向。
4、判断模块:蛇头撞墙或者碰到自己身体,则游戏结束,显示分数实现步骤本节分为两个部分,一部分为核心逻辑,即算法处理逻辑;另一部分为界面搭建。
游戏最核心的部分为算法逻辑部分。
先讲算法逻辑,最后再进行界面的搭建。
第一部分分为几个小节第二部分分为几个小节创建工程本次小游戏是一个单独的项目,所以需要创建单独的工程。
地图首先定义地图的长宽,定义数组存放地图上的点// 地图的宽(行)public static final int width = 35;// 地图的高(列)public static final int heigth = 8;//二维数组存放地图上的点private char[][] background = new char[heigth][width];我们需要的地图为:所以需要初始化地图,四周为墙壁,中间为空白部分,供蛇移动。
这里使用’*’代表墙壁,使用’ ’代表空白部分。
边界值判定:二维数组的第一行和最后一行,其余行的第一列和最后一列均为墙壁。
初始化方法:// 初始化地图public void initBackground() {for (int rows = 0; rows < background.length; rows++) {for (int cols = 0; cols < background[rows].length; cols++) {if (rows == 0 || rows == (heigth - 1) || cols == 0 || cols == (width - 1)) {background[rows][cols] = '*';} else {background[rows][cols] = ' ';}}}}展示,在控制台循环打印。
showBackground方法:public void showBackground() {for (int rows = 0; rows < background.length; rows++) {for (int cols = 0; cols < background[rows].length; cols++) {System.out.print(background[rows][cols]);}System.out.println();}}运行main方法,查看效果。
Main方法:public static void main(String[] args) throws Exception {SnakeGame snake = new SnakeGame();snake.initBackground();snake.showBackground();}控制台效果图:蛇前面已经初始化完成地图,然后进行蛇的初始化。
蛇的初始大小为3,一个蛇头两节身体。
为位置位于屏幕的正中央。
代码:// 集合保存节点信息LinkedList<Point> snake = new LinkedList<Point>();// 初始化蛇public void initSnake() {int x = width / 2;int y = heigth / 2;snake.add(new Point(x + 1, y));snake.add(new Point(x, y));snake.add(new Point(x - 1, y));}初始化蛇之后,要进行蛇的展示,蛇身用’#’,蛇头用’¥’表述。
这里写showSnake方法。
// 显示蛇public void showSnake() {// 蛇头Point head = snake.getFirst();background[head.y][head.x] = '¥';// 蛇身for (int i = 1; i < snake.size(); i++) {Point body = snake.get(i);background[body.y][body.x] = '#';}}修改main方法,将初始化蛇的方法和展示蛇的方法添加进main方法中:public static void main(String[] args) throws Exception {SnakeGame snake = new SnakeGame();snake.initBackground();snake.initSnake();snake.showSnake();snake.showBackground();}运行main方法及效果图:食物蛇的食物时随机出现的,位置不在墙壁上。
写方法createFood,判断位置是否在墙上,不在则可以创建食物,在则重新随机。
//食物Point food;public void createFood() {//食物随机,创建随机对象Random ra = new Random();while(true) {int x = ra.nextInt(width);int y = ra.nextInt(heigth);if(background[y][x] != '*') {food = new Point(x,y);break;}}}显示食物,用’@’符号表示食物。
//显示食物public void showFood() {background[food.y][food.x] = '@';}main方法加入食物创建和显示食物方法:public static void main(String[] args) throws Exception {SnakeGame snake = new SnakeGame();snake.initBackground();snake.initSnake();snake.showSnake();//初始化食物snake.createFood();snake.showFood();snake.showBackground();}运行main方法,查看效果:多运行几次,可以看到食物时随机出现的。
移动与吃食物蛇的移动分为四个方向,向上、向下、向左和向右。
移动的方式有两种,第一种,蛇的每一节都向前移动一格;第二种:添加蛇头,移除蛇尾。
我们这里采用添加蛇头,移除蛇尾的方式。
向上的时候,纵坐标减一://向上移动public void moveUp() {//获取蛇头Point head = snake.getFirst();//添加新蛇头snake.addFirst(new Point(head.x,head.y-1));//删除蛇尾snake.removeLast();}向下的时候,纵坐标加一://向下移动public void moveDown() {//获取蛇头Point head = snake.getFirst();//添加新蛇头snake.addFirst(new Point(head.x,head.y+1));//删除蛇尾snake.removeLast();}向左的时候,横坐标减一://向左移动public void moveLeft() {//获取蛇头Point head = snake.getFirst();//添加新蛇头snake.addFirst(new Point(head.x-1,head.y));//删除蛇尾snake.removeLast();}向右的时候,横坐标加一://向右移动public void moveRight() {//获取蛇头Point head = snake.getFirst();//添加新蛇头snake.addFirst(new Point(head.x+1,head.y));//删除蛇尾snake.removeLast();}在移动时,记录一个方向,如果按下的是反向键,则不改变方向。
public static final int UP_DIRECTION = 1;public static final int DOWN_DIRECTION = -1;public static final int LEFT_DIRECTION = 2;public static final int RIGHT_DIRECTION = -2;//默认为向右int currentDirection = -2;//相反方向public void changeDirection(int newDirection) {//判断当前方向与所按方向是否相反if(newDirection + currentDirection !=0) {this.currentDirection = newDirection;}}在移动的时候,要判读是否吃到食物。
public boolean eatFood() {Point head = snake.getFirst();//吃到食物if(head.equals(food)) {return true;}return false;}对移动进行优化,四个方法合并成一个:public void move() {if (!isGameOver) {Point head = snake.getFirst();// 蛇根据当前方向移动switch (currentDirection) {case UP_DIRECTION:snake.addFirst(new Point(head.x, head.y - 1));break;case DOWN_DIRECTION:snake.addFirst(new Point(head.x, head.y + 1));break;case RIGHT_DIRECTION:snake.addFirst(new Point(head.x + 1, head.y));break;case LEFT_DIRECTION:snake.addFirst(new Point(head.x - 1, head.y));break;default:}// 删除蛇尾// 如果吃到食物。