第三次实验

北京电子科技学院(BESTI)

实     验    报     告

课程:Java程序设计 班级:1353  姓名:黎静  学号:20135338

成绩:             指导教师:娄嘉鹏      实验日期:2015.6.03

实验密级:         预习程度:         实验时间:

仪器组次:          必修/选修:            实验序号:3

实验名称:   JAVA敏捷开发xp实验

实验内容:

 

1. XP基础

 

2. XP核心实践

 

3. 相关工具

实验要求:

 

1.没有Linux基础的同学建议先学习《Linux基础入门(新版)》《Vim编辑器》 课程

 

2.完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。报告可以参考范飞龙老师的指导

 

3. 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。

实验内容:

(一)敏捷开发与XP

编程学习是一个习而学的过程。 一个常见的公式是:软件工程=开发流程+工具 邹欣老师给出的两个公式:软件=程序+软件工程和软件企业=软件+商业模式 开发流程大家可以参考学习邹欣老师的软件团队和开发流程。常见的开发流程有:

  • RUP(Rational Unified Process)
  • PSP(Personal Software Process )
  • TSP(Team Software Process )
  • Agile Process
  • ……

敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法。敏捷流程是一系列价值观和方法论的集合。

(二)编码标准

编写代码一个重要的认识是程序大多时候是给人看的,编程标准使代码更容易阅读和理解,甚至可以保证其中的错误更少。

程序没有最基本的缩进,让人读起来很费劲,这个问题在Eclipse中比较容易解决,我们单击Eclipse菜单中的source->Format 或用快捷键Ctrl+Shift+F就可以按Eclipse规定的规范缩进

代码标准中很重要的一项是如何给包、类、变量、方法等标识符命名,能很好的命名可以让自己的代码立马上升一个档次。Java中的一般的命名规则有:

  • 要体现各自的含义
  • 包、类、变量用名词
  • 方法名用动宾
  • 包名全部小写,如:ioawt
  • 类名第一个字母要大写,如:HelloWorldApp
  • 变量名第一个字母要小写,如:userName
  • 方法名第一个字母要小写:setName
  • ...

标识符名字应当直观且可以拼读,可望文知意,不必进行解码,一般采用英文单词或其组合,便于记忆和阅读,切忌使用汉语拼音来命名,用词要准确例如当前值应该起名currentValue,写成nowValue就不准确了,但还凑合,写成dqz(dang qian zhi 首字母)就是笑话了。

标识符的长度“min-length && max-information”的原则,比如:maxVal 比 maxValueUntilOverflow要好些,可以通过去元音法把变量名变短,如returnValue->rtnVal ,message->msg;一般全局变量用具有说明性的名字,局部变量用短名字:单字符的名字,常见的如ijk等用作局部变量。

(三)结对编程

结 对编程是XP中的重要实践。在结对编程模式下,一对程序员肩并肩、平等地、互补地进行开发工作。他们并排坐在一台电脑前,面对同一个显示器,使用 同一个键盘、同一个鼠标一起工作。他们一起分析,一起设计,一起写测试用例,一起编码,一起做单元测试,一起做集成测试,一起写文档等。

 

 

(四)版本控制

XP的集体所有制意味着每个人都对所有的代码负责;这一点,反过来又意味着每个人都可以更改代码的任意部分。结对编程对 这一实践贡献良多:借由在不同的结对中工作,所有的程序员都能看到完全的代码。集体所有制的一个主要优势是提升了开发程序的速度,因为一旦代码中出现错 误,任何程序员都能修正它。 这意味着代码要放到一个大家都能方便获取的地方,我们叫代码仓库。这引出另外一个话题叫版本控制(Version Control)。

(五)重构

我们先看看重构的概念:

重构(Refactor),就是在不改变软件外部行为的基础上,改变软件内部的结构,使其更加易于阅读、易于维护和易于变更 。

重 构中一个非常关键的前提就是不改变软件外部行为,它保证了我们在重构原有系统的同时,不会为原系统带来新的BUG,以确保重构的安全。如何保证不改变 软件外部行为?重构后的代码要能通过单元测试。如何使其更加易于阅读、易于维护和易于变更 ?设计模式给出了重构的目标。

 

重构前:

重构后:

(六)

游戏项目  贪吃蛇

刘浩晨 黎静

源代码

import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;

import com.sun.xml.internal.ws.wsdl.writer.document.soap.Body;

public class Controller extends KeyAdapter implements SnakeListener/*,ActionListener*/ {
    private Snake snake;
    private Food food;
    private Ground ground;
    private GamePanel gamepanel;
    private Game game;

    public Controller(Snake snake, Food food, GamePanel gamepanel,Game game) {

        this.snake = snake;
        this.food = food;
        
        this.gamepanel = gamepanel;
        this.game=game;
    }

    public void snakeMoved(Snake snake) {
        if (food.isSnakeEatFood(snake)) {
            snake.eatFood();
            food.newFood(getPoint());
        }
        if (snake.isEatBody()) {
            snake.die();
        }
        gamepanel.disPlay(snake, food, ground);

    }
//新游戏开始
    public void newGame() {
        snake.start();
        food.newFood(getPoint());
    }
//随即产生食物的位置
    public Point getPoint() {
        Random radom = new Random();
        int x = radom.nextInt(Global.WIDTH);
        int y = radom.nextInt(Global.HEIGHT);
        return new Point(x, y);
    }
//按键处理
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
        case KeyEvent.VK_UP:
            snake.changeDirection(Snake.UP);
            break;
        case KeyEvent.VK_DOWN:
            snake.changeDirection(Snake.DOWN);
            break;
        case KeyEvent.VK_LEFT:
            snake.changeDirection(Snake.LEFT);
            break;
        case KeyEvent.VK_RIGHT:
            snake.changeDirection(Snake.RIGHT);
            break;
        case KeyEvent.VK_ADD:
        case KeyEvent.VK_PAGE_UP:
            snake.speedUp();// 加速
        break;
        case KeyEvent.VK_SUBTRACT:
        case KeyEvent.VK_PAGE_DOWN:
            snake.speedDown();// 减速
        break;
        }
    }

    }


    
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

public class Food extends Point {
//    蛇是否吃到食物?判断蛇头和食物的坐标是否相等,如果相等为吃到
    public boolean isSnakeEatFood(Snake snake) {   
        System.out.println("Food's issnakeeatfood");
        return this.equals(snake.getHead());

    }
//产生一个新食物
    public void newFood(Point p) {
        this.setLocation(p);
    }
//画出食物
    public void drawMe(Graphics g) {
        System.out.println("food's drawme");
        g.setColor(Color.BLUE);
        g.fill3DRect(x * Global.CELL_SIZE, y * Global.CELL_SIZE,
                Global.CELL_SIZE, Global.CELL_SIZE, true);
    }
}
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;

public class Game extends JFrame {
    JLabel bt1;
    JLabel bt2;

    JMenuItem jixu;
    JMenuItem zanting;
    JMenuItem tuichu;

    JRadioButton chu;
    JRadioButton zhong;
    JRadioButton gao;
    JRadioButton chao;

    JMenuItem guanyu;
    Font f;
    Snake snake = new Snake();

    GamePanel gamepanel = new GamePanel();
    Food food = new Food();
    Controller controller = new Controller(snake, food,gamepanel, this);

    void CreatFrame() {

        f = new Font("宋体", Font.PLAIN, 12);

        JMenuBar caidan = new JMenuBar();
        JMenu shezhi = new JMenu("设置");
        shezhi.setFont(f);
        JMenu nandu = new JMenu("难度");
        nandu.setFont(f);
        JMenu bangzhu = new JMenu("帮助");
        bangzhu.setFont(f);
        caidan.add(shezhi);
        caidan.add(nandu);
        caidan.add(bangzhu);

        jixu = new JMenuItem("继续 F2");
        jixu.setFont(f);
        jixu.addActionListener(new ToolListener());
        zanting = new JMenuItem("暂停 F3");
        zanting.setFont(f);

        zanting.addActionListener(new ToolListener());
        tuichu = new JMenuItem("退出 F4");
        tuichu.setFont(f);
        tuichu.addActionListener(new ToolListener());

        chu = new JRadioButton("初级,最快速度195", true);
        chu.setFont(f);
        chu.addActionListener(new ToolListener());
        zhong = new JRadioButton("中级,最快速度225");
        zhong.setFont(f);
        zhong.addActionListener(new ToolListener());
        gao = new JRadioButton("高级,最快速度255");
        gao.setFont(f);
        gao.addActionListener(new ToolListener());
        chao = new JRadioButton("超级,最快速度275");
        chao.setFont(f);
        chao.addActionListener(new ToolListener());
        ButtonGroup bg = new ButtonGroup();
        bg.add(chu);
        bg.add(zhong);
        bg.add(gao);
        bg.add(chao);
        nandu.add(chu);
        nandu.add(zhong);
        nandu.add(gao);
        nandu.add(chao);

        guanyu = new JMenuItem("关于");
        guanyu.setFont(f);
        guanyu.addActionListener(new ToolListener());

        shezhi.add(jixu);
        shezhi.add(zanting);
        shezhi.add(tuichu);

        bangzhu.add(guanyu);

        this.setJMenuBar(caidan);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(Global.WIDTH * Global.CELL_SIZE + 8, Global.HEIGHT
                * Global.CELL_SIZE + 49);
        gamepanel.setSize(Global.WIDTH * Global.CELL_SIZE, Global.HEIGHT
                * Global.CELL_SIZE);
        this.add(gamepanel, BorderLayout.CENTER);
        gamepanel.addKeyListener(controller);
        snake.addSnakeListener(controller);
        this.addKeyListener(controller);
        this.setResizable(false);
        this.setTitle("贪吃蛇-Worm1.0");
        this.setVisible(true);
        controller.newGame();

    }

    public static void main(String[] args) {
        Game game = new Game();
        game.CreatFrame();

    }

    public class ToolListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            if (e.getSource() == zanting) {
                snake.setZanTing();
            } else if (e.getSource() == jixu) {
                setJixu();
            } else if (e.getSource() == tuichu) {
                setTuiChu();

            } else if (e.getSource() == chu) {
                snake.setSD(300, 110);

            } else if (e.getSource() == zhong) {
                snake.setSD(250, 80);

            } else if (e.getSource() == gao) {
                snake.setSD(200, 50);

            } else if (e.getSource() == chao) {
                snake.setSD(150, 30);

            } else if (e.getSource() == guanyu) {
                JLabel gy = new JLabel("貪吃蛇WORM1.0版本 ,歡迎試玩!"
                        + "提示:加速:PAGE UP,减速:PAGE DOWN");
                gy.setFont(f);
                JOptionPane.showMessageDialog(null, gy);

            }
        }

        public void setTuiChu() {
            JLabel tc = new JLabel("确定退出吗?");
            tc.setFont(f);
            int a = JOptionPane.showConfirmDialog(null, tc);
            if (a == 0) {

                System.exit(0);
            }
        }

        private void setJixu() {

            controller.newGame();
            snake.life = true;

        }
    }

}
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JPanel;

public class GamePanel extends JPanel {

    private Snake snake;
    private Food food;
    private Ground ground;

    public void disPlay(Snake snake, Food food, Ground ground) {
        System.out.println("gamepanel's display");
        this.snake = snake;
        this.food = food;
        this.ground = ground;
        this.repaint();

    }

    public void paint(Graphics g) {
        g.setColor(new Color(0xcfcfcf));
        g.fillRect(0, 0, Global.WIDTH*Global.CELL_SIZE, Global.WIDTH*Global.CELL_SIZE);
        if(ground!=null&&food!=null&&snake!=null){
        this.food.drawMe(g);
        this.snake.drawMe(g);
        }
    }

}

public class Global {
public static final int CELL_SIZE=15;
public static final int WIDTH=20;
public static final int HEIGHT=20;
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

import javax.swing.JOptionPane;

public class Snake {
    Set<SnakeListener> listeners = new HashSet<SnakeListener>();
    LinkedList<Point> body = new LinkedList<Point>();
    public int oldDirection, newDirection;
    private Point oldTail;
    public boolean life;
    public static final int UP = 1, DOWN = -1, LEFT = 2, RIGHT = -2;
    public static int sd = 300;// 停滞时间
    public static int d = 200;// 最快多少;
    double speedChangeRate = 0.75;
//初始化Snake
    public Snake() {
        inti();
    }

    public Point getHead() {
        return body.getFirst();
    }

    private void inti() {
        int x = Global.WIDTH / 2;
        int y = Global.HEIGHT / 2;
        for (int i = 0; i < 2; i++) {
            body.addLast(new Point(x--, y));
        }
        oldDirection = newDirection = RIGHT;
        life = true;
    }
//蛇移动如果新方向和老方向不相反时,把新方向赋值给老方向
    public void move() {
        System.out.println("snake's Move");
        if (!(newDirection + oldDirection == 0)) {
            oldDirection = newDirection;
        }

        // 1.去尾
        oldTail = body.removeLast();
        int x = body.getFirst().x;
        int y = body.getFirst().y;
        switch (oldDirection) {
        case UP:
            y--;
            if (y < 0)

                this.die();

            break;
        case DOWN:
            y++;
            if (y > Global.HEIGHT)

                this.die();
            break;
        case LEFT:
            x--;
            if (x < 0)

                this.die();

            break;
        case RIGHT:
            x++;
            if (x >= Global.WIDTH)
                this.die();

            break;
        }
        Point newHead = new Point(x, y);
        // 2.添头
        body.addFirst(newHead);
    }

    public void changeDirection(int direction) {
        System.out.println("snake's changedirection");

        newDirection = direction;
    }
//吃到食物后,添加尾巴
    public void eatFood() {
        System.out.println("snake's eatfood");
        body.addLast(oldTail);
    }
//判断是否吃到身体(判断equals是否相等
    public boolean isEatBody() {
        System.out.println("snake's iseatbody");
        for (int i = 1; i < body.size(); i++) {
            if (body.get(i).equals(this.getHead())) {
                return true;
            }
        }
        return false;
    }

    public void drawMe(Graphics g) {
        g.setColor(Color.BLUE);
        System.out.println("snake's drawMe");
        for (Point p : body) {
            g.fill3DRect(p.x * Global.CELL_SIZE, p.y * Global.CELL_SIZE,
                    Global.CELL_SIZE, Global.CELL_SIZE, true);
        }
    }

    public class SnakeThread implements Runnable {

        public void run() {

            while (life) {
                move();
                for (SnakeListener l : listeners) {
                    l.snakeMoved(Snake.this);
                }
                if (sd <= d) {
                    sd = d;
                } else {
                    sd -= 5;
                }

                try {
                    Thread.sleep(sd);
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

            }
        }

    }

    public void start() {
        new Thread(new SnakeThread()).start();
    }

    public void addSnakeListener(SnakeListener l) {
        if (l != null) {
            this.listeners.add(l);
        }
    }
//线程死亡
    public void die() {
        life = false;
        JOptionPane.showMessageDialog(null, "游戏结束   ! ! !");
    }
//暂停键
    public void setZanTing() {
        if (life) {
            life = false;
        } else {
            life = true;

        }
    }

    public void setSD(int a, int b) {
        sd = a;
        d = b;

    }
//加速
    public void speedUp() {
        d *= speedChangeRate;

    }
//减速
    public void speedDown() {
        d /= speedChangeRate;
    }
}
public interface SnakeListener {
    void snakeMoved(Snake snake);
}

实验中遇到的问题:

游戏编写废了很长时间分析还有设计,难度很大

解决问题的方法:

有两个人,彼此协助,在网上查资料,翻书,而且同伴是个大神,所以还是很有意思的。由于要考虑和编写的实在太多,所以需要一个人负责编,一个人负责查。

 

 

统计的PSP(Personal Software Process)时间:

步骤

耗时(min)

百分比

需求分析

30

12.5%

设计

70

29.2%

代码实现

70

29.2%

测试

40

16.7%

分析总结

30

12.5%






 

 

 

 

 

 

 

 

posted on 2015-06-05 01:16  黑鬼仁西  阅读(374)  评论(0编辑  收藏  举报