贪吃蛇
2015-12-04 20:44
399 查看
贪吃蛇
Cell 是数据格子,是数据结构 Worm 是核心数据和算法的封装,包括爬行,碰撞,吃食物等 TestCase 是核心业务数据的测试案例,必须严格实现通过 Wormstage 1 是蛇的绘制面板,还充当了软件流程控制器的 作用:控制定时任务处理,和键盘输入流程控制creepTo()! Jframe 只是窗口容器。将Wormstage 显示出来。
源代码下载:http://download.csdn.net/download/u012234452/9327291
结构图
1、Cell.java
package com.feike.worm; /** 一个单元格子 */ public class Cell { private int x; private int y; public Cell() { } public Cell(int x, int y) { super(); this.x = x; this.y = y; } public String toString() { return "["+x+","+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; } }
2、Worm.java
package com.feike.worm; import java.util.Arrays; /** 贪吃蛇 */ public class Worm { public static final int DEFAULL_LENGTH = 12; private Cell[] cells; public static final int UP = 1; public static final int DOWN = -1; public static final int LEFT = 2; public static final int RIGHT = -2; /** 蛇当前的运行方向 */ private int currentDirection; public Worm() { cells = new Cell[DEFAULL_LENGTH]; for(int i=0;i<cells.length;i++){ cells[i] = new Cell(i,0);//[0,0][1,0][2,0][3,0]... } /**给蛇一个默认的爬行方向 */ currentDirection = DOWN; } public boolean contains(int x,int y){ for(int i= 0;i<cells.length;i++){ Cell node = cells[i]; if(node.getX()==x && node.getY()==y){ return true; } } return false; } /** * 1)计算currentDirection与direction的和, * 如果是0表示方向了,就结束方法返回,不进行任何动作 * 2)currentDirection = Direction 改变当前方向, * 作为下次运行的方向 * 3)判断当前头节点的坐标和食物对象的坐标一致 * 如果一致说明吃到食物了 * 4)如果吃到食物,就将cells数组进行扩容 * 将cells数组内容的每个元素向后移动。 * 5)将新头节点插入的头位置cells[0] = newHead * 6)返回是否吃到食物 */ public boolean creep(int direction,Cell food){ if(currentDirection + direction ==0){ return false;//反向了,不进行任何动作 } currentDirection = direction; Cell head = createHead(direction); /* boolean eat = false; if(head.getX()==food.getX() && head.getY()==food.getY()){ eat = true; }*/ boolean eat = head.getX()==food.getX() && head.getY()==food.getY(); if(eat){ //如果吃了 就扩容 cells = Arrays.copyOf(cells, cells.length+1); } for(int i=cells.length-1;i>=1;i--){ cells[i] = cells[i-1]; } cells[0] = head; return eat; } /** 重载一下方便使用 看当前方向*/ public boolean creep(Cell food){ return creep(currentDirection,food); } /** 爬 */ public void creep(){ for(int i=cells.length-1;i>=1;i--){ cells[i] = cells[i-1]; } cells[0] = createHead(currentDirection); } /** 看当前方向是否会碰撞*/ public boolean hit(){ return hit(currentDirection); } /** 检查是否撞墙或撞到自己*/ public boolean hit(int direction){ System.out.println("方向(2): "+direction);//检查方向 Cell head = createHead(direction); System.out.println(head);//检查头坐标位置 if(currentDirection + direction ==0){ return false;//反向了,不进行任何动作 } if(head.getX()<0 || head.getX()>=WormStage.COLS || head.getY()<0 || head.getY()>WormStage.ROWS){ //if(true)这撞在墙上了,返回true return true; } for(int i=0;i<cells.length-1;i++){ Cell node = cells[i]; if(node.getX()==head.getX() && node.getY()==head.getY()){ return true; } } return false; } /** 头节点的移动*/ private Cell createHead(int direction){ int x = cells[0].getX(); int y = cells[0].getY(); switch (direction) { case DOWN: y++; break; case UP: y--; break; case LEFT: x--; break; case RIGHT: x++; break; } return new Cell(x,y); } /** Worm.java */ public Cell[] getCells(){ // return cells; //下面这专业点 return Arrays.copyOf(cells, cells.length); } public String toString() { return Arrays.toString(cells); } }
3、WormStage.java
package com.feike.worm; import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.security.PublicKey; import java.util.Random; import java.util.Timer; import java.util.TimerTask; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.LineBorder; public class WormStage extends JPanel{ /** 行数*/ public static final int ROWS = 35; /** 列数*/ public static final int COLS = 35; /** 格子大小 10个像素大小*/ public static final int CELL_SIZE = 10; private Worm worm; private Cell food; public WormStage() { worm = new Worm(); food = createFood(); } /** 生成一个食物 * 1 生成随机数x,y * 2 检查蛇是否包含x,y * 2.1 如果包含 返回 1 * 3 创建食物节点。 * */ private Cell createFood(){ int x; int y; Random r = new Random(); do{ x = r.nextInt(COLS); y = r.nextInt(ROWS); }while(worm.contains(x,y)); return new Cell(x,y); } public String toString(){ return "worm:"+worm+"\nfood:"+food; } /** 重写绘图方法*/ public void paint(Graphics g){ //填充背景色 g.setColor(Color.DARK_GRAY); g.fillRect(0, 0, getWidth(), getHeight()); //绘制食物 g.setColor(Color.RED); g.fill3DRect(CELL_SIZE*food.getX(), CELL_SIZE*food.getY(), CELL_SIZE, CELL_SIZE, true); //绘制蛇 g.setColor(Color.GREEN); Cell[] cells = worm.getCells(); for(int i=0;i<cells.length;i++){ Cell node = cells[i]; g.fill3DRect(CELL_SIZE*node.getX(), CELL_SIZE*node.getY(), CELL_SIZE, CELL_SIZE, true); } } public static void main(String[] args) { //启动软件 WormStage.java JFrame frame = new JFrame("贪吃蛇"); WormStage pane = new WormStage(); frame.setLayout(null);// 取消窗口的默认布局,取消自动充满 frame.add(pane);// 窗口添加面板 pane.setSize(CELL_SIZE*COLS, CELL_SIZE*ROWS);//面板大小 pane.setLocation(50, 50);//面板位置 frame.setSize(450, 480);//设置窗口的大小 pane.setBorder(new LineBorder(Color.black));//添加边框 frame.setLocationRelativeTo(null);//frame居中 frame.setVisible(true);//显示窗口 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pane.action();//启动蛇的运行 } /**行为 */ private void action(){ /* worm.creep(food); swing JPanel 中声明的方法,会尽快的启动重绘功能, 尽快调用paint(g)方法绘制界面 repaint();*/ Timer timer = new Timer(); timer.schedule(new TimerTask(){ public void run(){ //爬行控制逻辑 if(worm.hit()){ worm = new Worm(); food = createFood(); }else{ boolean eat = worm.creep(food); if(eat){ food = createFood(); } } worm.creep(food); repaint(); } }, 0,1000/7); //this 就是当前舞台面板 this.requestFocus();//获得焦点 this.addKeyListener(new KeyAdapter(){ public void keyPressed(KeyEvent e){ //key 代表哪个按键被按下! int key = e.getKeyCode(); switch (key) { case KeyEvent.VK_UP: //上箭头按下 creepTo(Worm.UP); break; case KeyEvent.VK_DOWN: //下箭头按下 creepTo(Worm.DOWN); break; case KeyEvent.VK_LEFT: //左箭头按下 creepTo(Worm.LEFT); break; case KeyEvent.VK_RIGHT: //右箭头按下 creepTo(Worm.RIGHT); break; } } });//addKeyListener }//action() /** 爬行控制方法,在按键按下时调用*/ private void creepTo(int direction){ if(worm.hit(direction)){ worm = new Worm(); food = createFood(); }else { boolean eat = worm.creep(direction,food); if(eat){ food = createFood(); } } repaint(); } }//wormStage
下面代码是用作测试用的
1、TestCase.java
package com.feike.test; import org.junit.Test; import com.feike.worm.*; /** * test 测试 * test 案例 * */ public class TestCase { @Test //来自JUnit的注释标记,用于执行测试方法 public void testWormInit(){ System.out.println("测试Worm构造器"); Worm worm = new Worm(); System.out.println(worm); } @Test public void testWormContains(){ System.out.println("测试Worm包含算法"); Worm worm = new Worm(); System.out.println(worm.contains(2, 0));//true System.out.println(worm.contains(5, 6));//false } @Test public void testWormStage(){ System.out.println("创建舞台实例"); WormStage stage = new WormStage(); System.out.println(stage); } @Test public void testCreep(){ System.out.println("爬行测试"); Worm worm = new Worm(); System.out.println(worm); worm.creep(); System.out.println(worm); } @Test public void testCreepForFood(){ System.out.println("检查食物的爬行"); Worm worm = new Worm(); Cell food = new Cell(1,2); System.out.println(worm.creep(Worm.DOWN, food)); System.out.println(worm); System.out.println(worm.creep(Worm.DOWN, food)); System.out.println(worm); System.out.println(worm.creep(Worm.RIGHT, food)); System.out.println(worm); } @Test public void testHit(){ System.out.println("碰撞测试"); Worm worm = new Worm(); Cell food = new Cell(10,10); System.out.println(worm); System.out.println(worm.creep(Worm.DOWN, food)); System.out.println(worm); System.out.println(worm.creep(Worm.DOWN, food)); System.out.println(worm); System.out.println(worm.hit(Worm.LEFT));//true System.out.println(worm.hit(Worm.RIGHT));//false System.out.println(worm.creep(Worm.RIGHT, food)); System.out.println(worm); System.out.println(worm.creep(Worm.RIGHT, food)); System.out.println(worm); System.out.println(worm.creep(Worm.UP, food)); System.out.println(worm); System.out.println(worm.hit(Worm.UP));//true } }
2、Test.java
package com.feike.test; import com.feike.worm.Worm; /** * 测试默认创建的贪吃蛇对象 * */ public class Test { public static void main(String[] args) { Worm worm = new Worm(); System.out.println(worm); } }
3、JFrameDemo.java
package com.feike.test; import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame;// Frame 相框,框架 import javax.swing.JPanel;// panel 面板 import javax.swing.border.LineBorder; /** 显示窗口 与 绘图 */ public class JFrameDemo { public static void main(String[] args) { JFrame frame = new JFrame("窗口"); Stage pane = new Stage(); frame.setLayout(null);// 取消窗口的默认布局,取消自动充满 frame.add(pane);// 窗口添加面板 pane.setSize(10 * 35, 10 * 35);//面板大小 pane.setLocation(50, 50);//面板位置 frame.setSize(450, 480);//设置窗口的大小 pane.setBorder(new LineBorder(Color.black));//添加边框 frame.setLocationRelativeTo(null);//frame居中 frame.setVisible(true);//显示窗口 //在Swing中如下代码可以实现对键盘事件的监听, //也就是获得到底那个键盘按键被按下了 pane.requestFocus();//使pane获取输入“焦点”, //也就是使pane变成键盘输入的目标 //pane.addKeyListener(new KeyListener(){ //继承KeyAdapter比实现KeyListener 更加简洁。 //在pane上添加键盘事件的监听,获得到底哪个按键被按下 pane.addKeyListener(new KeyAdapter(){ //在按键按下的时候执行的方法 public void keyPressed(KeyEvent e) { System.out.println("hi"+e.getKeyCode()); } /*//在按键释放的时候执行 public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { }*/ }); } } class Stage extends JPanel{ /** 重写了 默认的绘图方法*/ public void paint(Graphics g){//paint g.setColor(Color.darkGray);//深灰色 g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(Color.RED); g.fill3DRect(50, 50, 30, 20, true); } }
相关文章推荐
- Android之使用Http协议实现文件上传功能
- mysql集群之MMM简单搭建
- 通晓网络测试常用命令
- Nodejs学习笔记之测试驱动
- 可以测试javascript运行效果的代码
- 使用php测试硬盘写入速度示例
- python 测试实现方法
- 举例详解PHP脚本的测试方法
- Php-Redis安装测试笔记
- mysql压力测试脚本实例
- JavaScript 组件之旅(四):测试 JavaScript 组件
- Android触屏测试实例代码
- 解析libcurl在android下的移植、编译与测试
- 几个比较实用的JavaScript 测试及效验工具
- Java中对AtomicInteger和int值在多线程下递增操作的测试
- Python实现测试磁盘性能的方法
- python自动化测试实例解析
- Python之PyUnit单元测试实例
- Appium自动化测试系列2- 写一个Python测试脚本来测试一下YY语音
- IOS UI Automation 学习之常用类,方法和模拟手势