Java贪吃蛇,部分实现,适合作为新手练习作业。
2013-12-02 19:13
489 查看
一、概要设计
游戏规则:
由于基本都玩过,再次不在啰嗦。
游戏要素:
1、地图(map)
2、蛇(snake)
3、食物(food)
4、规则(rule)
输入设定:
1、通过键盘上的上、下、左、右进行游戏控制。
2、通过键盘的P控制游戏的暂停(pause)/开始(start)、N(new)控制新的一局的开始。
输出内容:(*为特定条件下激活)
1 、 游戏速度
2 、 游戏进行时间
3 、 贪吃蛇长度
4*、显示游戏结束信息
基本游戏默认参数:
1、地图大小(20X20)
2、地图单元格width = 20, height =20;
3、游戏速度为 (1051 - level*50)ms 初始等级为1,最高等级为20.
4、初始贪吃蛇长度为3
规则:
1、贪吃蛇碰触墙壁或者自身时,游戏结束。
2、贪吃蛇不能朝反方向进行移动。 ( 即:若当前贪吃蛇头部朝向的方向为南,则向北移动是无效的操作。)
3、贪吃蛇达到一定长度时,游戏结束。
4、食物位置随机生成。
未完成部分:
见Snack类中moveTo()方法的TODO标签处。
作业:
1、实现贪吃虫的自动移动。
2、增加游戏计时功能。(游戏时间)
3、增加暂停功能。
4、处理不同因移动造成的情况,进行相应处理
二、详细设计
画布类(Canvas):
贪吃蛇类(Snack):
游戏主界面类(GameFrame):
游戏规则:
由于基本都玩过,再次不在啰嗦。
游戏要素:
1、地图(map)
2、蛇(snake)
3、食物(food)
4、规则(rule)
输入设定:
1、通过键盘上的上、下、左、右进行游戏控制。
2、通过键盘的P控制游戏的暂停(pause)/开始(start)、N(new)控制新的一局的开始。
输出内容:(*为特定条件下激活)
1 、 游戏速度
2 、 游戏进行时间
3 、 贪吃蛇长度
4*、显示游戏结束信息
基本游戏默认参数:
1、地图大小(20X20)
2、地图单元格width = 20, height =20;
3、游戏速度为 (1051 - level*50)ms 初始等级为1,最高等级为20.
4、初始贪吃蛇长度为3
规则:
1、贪吃蛇碰触墙壁或者自身时,游戏结束。
2、贪吃蛇不能朝反方向进行移动。 ( 即:若当前贪吃蛇头部朝向的方向为南,则向北移动是无效的操作。)
3、贪吃蛇达到一定长度时,游戏结束。
4、食物位置随机生成。
未完成部分:
见Snack类中moveTo()方法的TODO标签处。
作业:
1、实现贪吃虫的自动移动。
2、增加游戏计时功能。(游戏时间)
3、增加暂停功能。
4、处理不同因移动造成的情况,进行相应处理
二、详细设计
画布类(Canvas):
import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.util.Vector; import javax.swing.JPanel; public class Canvas extends JPanel{ /** * */ private static final long serialVersionUID = 1L; /*画布参数*/ public static final int PADDING = 10; //画布内边距 public static final int CELL_SIZE = 20; //单元格大小 public static final int CELL_COLUMN = 20; //单元格列数 public static final int CELL_ROW = 20; //单元格行数 public static final Color BACKGROUND = Color.WHITE; //画布背景颜色 public int canvasWidth = 2*PADDING + CELL_SIZE*CELL_COLUMN; public int canvasHeight = 2*PADDING + CELL_SIZE*CELL_ROW; /*画布中的对象*/ public Snake snake; //贪吃蛇 private GameMap map; //地图(容器) // ------------------------------------ // 构造方法 // ------------------------------------ public Canvas() { setPreferredSize(null); //设置面板大小 startGame(); } /*从Point坐标值转换为swing中的坐标值*/ public int transformX(int pointX){ return 0;} public int transformY(int pointY){ return 0;} /*开始游戏*/ public void startGame(){ map = new GameMap(); snake = new Snake(map); /*初始化开始一条位置,并且长度为3的贪吃蛇*/ snake.enqueue(map.getPoint(10, 12)); snake.enqueue(map.getPoint(10, 11)); snake.enqueue(map.getPoint(10, 10)); map.randomFood(snake); } /*绘制界面*/ @Override public void paint(Graphics g) { super.paint(g); /*绘制网格,测试用*/ // for(int i=0;i<=CELL_COLUMN;i++) // g.drawLine(PADDING, PADDING+CELL_SIZE*i, PADDING +CELL_SIZE*CELL_COLUMN, PADDING+CELL_SIZE*i); // for(int i=0;i<=CELL_ROW;i++) // g.drawLine(PADDING + CELL_SIZE*i, PADDING, PADDING + CELL_SIZE*i, PADDING + CELL_SIZE*CELL_ROW); /*画贪吃蛇*/ Vector<Point> body = snake.getBody(); for(int i=0;i<body.size();i++){ /*头部画黄色*/ Point p = body.get(i); if(i == body.size()-1){ Color oldColor = g.getColor(); g.setColor(Color.yellow); g.fillRect((int)p.getX(),(int) p.getY(), CELL_SIZE, CELL_SIZE); g.setColor(oldColor); }else g.fillRect((int)p.getX(),(int) p.getY(), CELL_SIZE, CELL_SIZE); } /*画食物*/ Point food = map.getFood(); if(food != null){ //画食物 Color oldColor = g.getColor(); g.setColor(Color.red); g.fillRect((int)food.getX(), (int)food.getY(), CELL_SIZE, CELL_SIZE); g.setColor(oldColor); } } /*重载设置面板大小*/ @Override public void setPreferredSize(Dimension d) { super.setPreferredSize(new Dimension(canvasWidth,canvasHeight)); } }地图类(GameMap):
import java.awt.Point; import java.util.Random; public class GameMap { /*地图坐标*/ public Point[][] map; /*食物坐标*/ private Point food; /*构造方法*/ public GameMap() { map = new Point[Canvas.CELL_ROW][Canvas.CELL_COLUMN]; for (int i=0;i<Canvas.CELL_ROW ;i++) { for (int j=0;j<Canvas.CELL_COLUMN;j++) { map[i][j] = new Point(Canvas.PADDING+Canvas.CELL_SIZE*i,Canvas.PADDING+Canvas.CELL_SIZE*j); } } } /*得到指定位置的X,Y坐标*/ public Point getPoint(int row,int column){ return map[row][column]; } /*得到指定point所在map中的索引*/ public int[] pointAt(Point p){ int row = (int) ( (p.getX()-Canvas.PADDING) / Canvas.CELL_SIZE); int column = (int)( (p.getY()-Canvas.PADDING) / Canvas.CELL_SIZE); return new int[]{row,column}; } /*随机生成食物坐标*/ public Point randomFood(Snake snake){ Random random = new Random(); int xPos = random.nextInt(Canvas.CELL_ROW); int yPos = random.nextInt(Canvas.CELL_COLUMN); while(true){ if( !snake.getBody().contains(getPoint(xPos, yPos)) ){ food = getPoint(xPos, yPos); return food; }else { xPos = random.nextInt(Canvas.CELL_ROW); yPos = random.nextInt(Canvas.CELL_COLUMN); } } } /*设置食物位置*/ public void setFood(Point food){ this.food = food; } /*得到食物位置*/ public Point getFood(){ return food; } }
贪吃蛇类(Snack):
import java.util.Vector; import java.awt.Point; public class Snake { /*贪吃蛇在地图中的点集合,[0]元素为蛇头,[size-1]元素为蛇尾*/ private Vector<Point> body; /*贪吃蛇所在地图*/ private GameMap map; /*构造方法*/ public Snake(GameMap map){ this.map = map; body = new Vector<Point>(); } /*贪吃蛇移动或进食*/ public void enqueue(Point p) { body.add(p); } /*判断贪吃蛇是否为空*/ public boolean isEmpty(){ return size() == 0; } /*返回贪吃蛇的长度*/ public int size() { return body.size(); } /*返回贪吃蛇头部的位置*/ public Point getHead() { if(size()==0) throw new RuntimeException("贪吃蛇无头部"); return body.get(size()-1); } /*返回贪吃蛇尾部的位置*/ public Point getTail() { if(size()==0) throw new RuntimeException("贪吃蛇无尾部"); return body.get(0); } /*返回头部后的第一个位置*/ public Point getHeadAfter(){ if(size()==1) throw new RuntimeException("贪吃蛇只有头部"); return body.get(size()-2); } /*移除尾部*/ public void removeTail(){ body.remove(0); } /*返回整个贪吃蛇*/ public Vector<Point> getBody(){ return body; } // ----------------------------------- // 贪吃蛇行为 // ----------------------------------- /*是否为身体一部分*/ public boolean isBody(Point p){ if(body.contains(p)) return true; return false; } /*贪吃蛇移动到地图指定点*/ public void moveTo(int row,int column) { /*得到头部后第一个位置*/ Point afterHead = getHeadAfter(); /*判断要移动的位置是否有效*/ if(!moveValid(row, column)){ //TODO // // 添加你的处理方法,并将游戏结束 // System.out.println("碰到墙壁了!"); return; } /*判断是否为无效反方向移动*/ if(map.getPoint(row, column).equals(afterHead)){ //TODO // // 添加你的处理方法,但游戏继续 // System.out.println("无效的反方向操作!"); return; } /*判断是否碰到身体*/ if(isBody(map.getPoint(row, column))){ //TODO // // 添加你的处理方法,并将游戏结束 // System.out.println("碰到身体了!"); return; } /*判断是否移动到食物上*/ if(map.getPoint(row, column).equals(map.getFood())){ /*将食物添加到贪吃蛇身体中*/ enqueue(map.getPoint(row, column)); /*重新生成食物*/ map.randomFood(this); }else{ /*进行普通的移动*/ enqueue(map.getPoint(row, column)); removeTail(); } } /*贪吃蛇向左移动*/ public void moveLeft(){ /*得到头部位置*/ Point head = getHead(); int[] cood = map.pointAt(head); moveTo(cood[0]-1, cood[1]); } /*贪吃蛇向右移动*/ public void moveRight(){ /*得到头部位置*/ Point head = getHead(); int[] cood = map.pointAt(head); moveTo(cood[0]+1, cood[1]); } /*贪吃蛇向上移动*/ public void moveUp(){ /*得到头部位置*/ Point head = getHead(); int[] cood = map.pointAt(head); moveTo(cood[0], cood[1]-1); } /*贪吃蛇向下移动*/ public void moveDown(){ /*得到头部位置*/ Point head = getHead(); int[] cood = map.pointAt(head); moveTo(cood[0], cood[1]+1); } /*贪吃蛇移动是否有效*/ public boolean moveValid(int r,int c){ if( r < 0 || r >= Canvas.CELL_ROW || c < 0 || c >= Canvas.CELL_COLUMN) return false; return true; } }
游戏主界面类(GameFrame):
import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; public class GameFrame extends JFrame implements KeyListener{ /** * */ private static final long serialVersionUID = 1L; private Canvas canvas; /*构造方法*/ public GameFrame(){ init(); } /*初始化*/ private void init(){ this.setTitle("贪吃蛇 by:luiyikeke"); canvas = new Canvas(); add(canvas); /*添加画布到主面板*/ pack(); /*自适应大小*/ setResizable(false); /*禁止调整窗口大小*/ setLocationRelativeTo(null); /*窗口屏幕居中显示*/ this.addKeyListener(this); } public static void main(String[] args) { new GameFrame().setVisible(true); } @Override public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (38 == keyCode) { canvas.snake.moveUp(); } else if (37 == keyCode) { canvas.snake.moveLeft(); } else if (39 == keyCode) { canvas.snake.moveRight(); } else if (40 == keyCode) { canvas.snake.moveDown(); } canvas.repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } }
相关文章推荐
- Android ListView和Fragment结合使用,类似于某电商的实现,拿来就能用,详细标注适合新手
- Windows Phone 7 Dev (WP7 开发其实很简单) 稍微讲解_微软商店上架应用<<猜数字>>,适合初学者作为小练习,但是也很耗时
- Android ListView和Fragment结合使用,类似于某电商的实现,拿来就能用,详细标注适合新手
- 适合新手学习的laravel接入微信接口,实现微信公众号二次开发
- 循环嵌套作业(新手练习 大神勿喷)
- 新手上路系列5:部分字符串使用函数的程序实现
- 【重构练习】大二作业 第2部分
- 400行代码实现双人对战五子棋(适合新手入门)
- 一个特别适合新手练习的Android小项目——每日一妹纸
- 经典的SQL语句,适合新手练习使用(一)
- jquery实现的简单轮播图功能【适合新手】
- 《算法导论》第六章----优先级队列(代码实现+部分练习)
- 【重构练习】大二作业 第3部分
- jsp实现的简单分页,适合新手用
- 优先级队列(代码实现+部分练习)
- (4.2.26)一个特别适合新手练习的Android小项目——每日一妹纸
- ps教程-简单几部实现ps原创磨皮去黑痣-适合新手
- c语言选择结构作业题练习分享第二部分(附答案、考点、难度、分析)
- 快速排序c++实现--将未排序部分的最后一个数作为主元
- 新手作业:用JAVA实现双色球彩票系统