贪吃蛇

来源:互联网 发布:杭州淘宝村在哪里 编辑:程序博客网 时间:2024/04/30 15:24

贪吃蛇

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);    }}
0 0
原创粉丝点击