贪吃蛇

贪吃蛇

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值