您的位置:首页 > 编程语言 > Java开发

贪吃蛇

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java-贪吃蛇 测试