zoukankan      html  css  js  c++  java
  • java第三次实验

    北京电子科技学院(BESTI)

                  

    课程:Java程序设计   班级:1352       姓名:陈实  学号:20135224

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

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

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

    实验名称:                敏捷开发与XP实践                           

    实验目的与要求:                                                        

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

                                                                         

    实验仪器:

    名称

    型号

    数量

    Pc

     

    1

     

     

     

    重构:

    一、一个完整的重构流程包括:

    1. 从版本控制系统代码库中Check out code
    2. 读懂代码(包括测试代码)
    3. 发现bad smell
    4. Refactoring
    5. 运行所有的Unit Tests
    6. 往代码库中Check in code

    二、重构技能

    三、何时需要重构

    四、举例:

    rename

    move

    TDD测试:

    游戏: TankGame

    游戏描述:控制己方tank击杀敌方坦克。方向键控制移动,ctrl发射子弹,shift发射超级子弹,F1复活。

    代码如下:

    package MyFrame;

    import java.awt.Color;

    public class Constant {
    public static final int FX=400;
    public static final int FY=100;
    public static final int FWID=800;
    public static final int FHEI=600;
    public static final int TW=30;
    public static final int TH=30;
    public static final Color BACK=new Color(0,0,255);
    public static final int TSPEED=7;
    public static final int MissileW=10;
    public static final int MissileH=10;
    public static final int MSPEED=10;
    public static final int WW=50;
    public static final int WH=300;
    }

    package MyFrame;

    import java.awt.Color;
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.HeadlessException;
    import java.awt.Image;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.util.ArrayList;
    import java.util.List;

    import Mygame.Explode;
    import Mygame.Missile;
    import Mygame.Tank;
    import Mygame.Tank.Direction;
    import Mygame.greatWall;

    public class MyFrame extends Frame {
    public Tank t1 = new Tank(Constant.FWID - Constant.TW, Constant.FHEI
    - Constant.TH, true, Direction.STOP, this);
    public List<Missile> missiles = new ArrayList<Missile>();
    public List<Tank> enemyTanks = new ArrayList<Tank>();
    public List<Explode> bongs = new ArrayList<Explode>();
    public greatWall gw = new greatWall(500, 300);
    public static int EnemyCount = 10;
    public static int Times = 0;
    Image offScreenImage = null;

    public void launchFrame() {
    addEmpty();
    setTitle("TankWar");
    setBounds(Constant.FX, Constant.FY, Constant.FWID, Constant.FHEI);
    setVisible(true);
    setBackground(Constant.BACK);
    addWindowListener(new WindowAdapter() {

    @Override
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }

    });
    setResizable(false);
    new Thread(new TThread()).start();
    addKeyListener(new keyMonitor());

    }

    /**
    * 双缓冲技术就是在屏幕背后再定义一张图 在图上画有相同的背景 在闪烁的时候把图画到前面
    */
    @Override
    public void update(Graphics g) {// 双缓冲消除闪烁
    if (offScreenImage == null) {
    offScreenImage = this.createImage(Constant.FWID, Constant.FHEI);
    }
    Graphics gOffScreen = offScreenImage.getGraphics();// 获得画屏幕后面场景的画笔
    Color c = gOffScreen.getColor();
    gOffScreen.setColor(Constant.BACK);
    gOffScreen.fillRect(0, 0, Constant.FWID, Constant.FHEI);
    gOffScreen.setColor(c);
    paint(gOffScreen);
    g.drawImage(offScreenImage, 0, 0, null);// 把图片画到前面

    }

    @Override
    public void paint(Graphics g) {
    if (enemyTanks.size() == 0) {
    Times++;
    EnemyCount += 5;
    addEmpty();
    }
    g.drawString("子弹数:" + missiles.size(), 700, 50);
    g.drawString("敌方坦克数:" + enemyTanks.size(), 700, 70);
    g.drawString("关卡数:" + Times, 700, 90);
    g.drawString("血量:" + t1.getLife(), 700, 100);
    g.drawString("复活次数:" + t1.getTimes(), 700, 120);
    gw.draw(g);
    for (int i = 0; i < missiles.size(); i++) {
    Missile missile = missiles.get(i);
    if (missile.destroy(enemyTanks) || missile.destroy(t1)
    || missile.hitWall(gw)) {
    missiles.remove(i);
    }
    if (missile.isLive()) {
    missile.draw(g);
    }
    }
    t1.draw(g);
    for (int i = 0; i < enemyTanks.size(); i++) {
    Tank tank = enemyTanks.get(i);
    tank.hitWall(gw);
    tank.pengTank(enemyTanks);
    if (tank.isLive())
    tank.draw(g);
    }
    for (int i = 0; i < bongs.size(); i++) {
    Explode e = bongs.get(i);
    if (e.isLive()) {
    e.draw(g);
    } else {
    bongs.remove(i);
    }
    }

    }

    public void addEmpty() {
    for (int i = 0; i < EnemyCount; i++) {
    Tank tanki = new Tank(i * 50 + Constant.TW, 50, false, Direction.D,
    this);
    enemyTanks.add(tanki);
    }
    }

    private class keyMonitor extends KeyAdapter {

    @Override
    public void keyPressed(KeyEvent e) {
    t1.keypressed(e);

    }

    @Override
    public void keyReleased(KeyEvent e) {
    t1.keyReleased(e);
    }

    }

    private class TThread implements Runnable {

    public void run() {
    while (true) {
    repaint();
    try {
    Thread.sleep(50);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    }

    }

    package Mygame;

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

    import MyFrame.MyFrame;

    public class Explode {
    private int x,y;
    private boolean live=true;
    int[] zhiJing={2,4,8,15,16,20,16,10,5,2};
    private int step=0;
    MyFrame mf=null;
    public Explode(int x,int y,MyFrame mf) {
    this.x = x;
    this.y = y;
    this.mf=mf;
    }

    public boolean isLive() {
    return live;
    }

    public void setLive(boolean live) {
    this.live = live;
    }

    public void draw(Graphics g){
    if(!live)return;
    if(step==zhiJing.length){
    live=false;
    step=0;
    return;
    }
    Color c=g.getColor();
    g.setColor(Color.BLACK);
    g.fillOval(x, y, zhiJing[step], zhiJing[step]);
    g.setColor(c);
    step++;
    }
    }

    package Mygame;

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Rectangle;

    import MyFrame.Constant;

    public class greatWall {
    private int x,y;
    private int wid=Constant.WW;
    private int hei=Constant.WH;
    public greatWall(int x, int y) {
    this.x = x;
    this.y = y;
    }
    public void draw(Graphics g){
    Color c=g.getColor();
    g.setColor(Color.GRAY);
    g.fillRect(x, y, wid, hei);
    g.setColor(c);
    }
    public Rectangle getRect(){
    return new Rectangle(x,y,wid,hei);
    }
    }

    package Mygame;

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Rectangle;
    import java.util.List;

    import MyFrame.Constant;
    import MyFrame.MyFrame;
    import Mygame.Tank.Direction;

    public class Missile {
    private int x, y;
    private int missileW=Constant.MissileW;
    private int missileH=Constant.MissileH;
    private int Mspeed = Constant.MSPEED;
    private boolean live = true;
    private boolean good = true;
    MyFrame mf;
    Tank.Direction dir;

    public Missile(int x, int y, Tank.Direction dir, boolean good ,MyFrame mf) {
    this.x = x;
    this.y = y;
    this.mf=mf;
    this.dir = dir;
    this.good = good;
    }

    public void draw(Graphics g) {
    if (live == true) {
    Color c = g.getColor();
    if(good)
    g.setColor(Color.orange);
    else 
    g.setColor(Color.BLACK);
    g.fillOval(x, y, missileW, missileH);
    g.setColor(c);
    fly();
    }
    }
    public boolean hitWall(greatWall gw){
    if(this.isLive()&&this.getRect().intersects(gw.getRect())){
    this.setLive(false);
    Explode ex = new Explode(x,y,mf);
    mf.bongs.add(ex);
    return true;
    }
    return false;
    }
    public boolean isLive() {
    return live;
    }

    public void setLive(boolean live) {
    this.live = live;
    }

    public void fly() {
    switch (dir) {
    case L:
    x -= Constant.MSPEED;
    break;
    case LU:
    x -= Constant.MSPEED;
    y -= Constant.MSPEED;
    break;
    case LD:
    x -= Constant.MSPEED;
    y += Constant.MSPEED;
    break;
    case R:
    x += Constant.MSPEED;
    break;
    case RU:
    x += Constant.MSPEED;
    y -= Constant.MSPEED;
    break;
    case RD:
    x += Constant.MSPEED;
    y += Constant.MSPEED;
    break;
    case U:
    y -= Constant.MSPEED;
    break;
    case D:
    y += Constant.MSPEED;
    break;
    case STOP:
    break;
    }
    if (x <= 25 || x >= Constant.FWID - Constant.MissileW || y <= 0
    || y >= Constant.FHEI - Constant.MissileH) {
    live = false;
    mf.missiles.remove(this);
    }
    }

    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;
    }

    public Rectangle getRect() {
    Rectangle r = new Rectangle(x, y, Constant.MissileW, Constant.MissileH);
    return r;
    }

    public boolean destroy(Tank t1) {
    if (this.isLive() && this.getRect().intersects(t1.getRect())
    && t1.isLive() && this.good != t1.isGood()) {
    Explode ex = new Explode(x,y,mf);
    mf.bongs.add(ex);
    if(t1.isGood()){
    this.setLive(false);
    if(t1.getLife()>0){
    t1.setLife(t1.getLife()-20);
    }
    if(t1.getLife()==0){
    t1.setLive(false);
    }
    }else{
    t1.setLive(false);
    this.setLive(false);
    }
    return true;
    }
    return false;
    }

    public boolean destroy(List<Tank> enemyTanks) {
    for (int i = 0; i < enemyTanks.size(); i++) {
    Tank enemyTank = enemyTanks.get(i);
    if (destroy(enemyTank)) {
    enemyTank.setLive(false);
    enemyTanks.remove(i);
    return true;
    }
    }
    return false;
    }
    }

    package Mygame;

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Rectangle;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.List;
    import java.util.Random;

    import MyFrame.Constant;
    import MyFrame.MyFrame;

    /**
    * 如果想用MyFrame中的成员或者方法必须在构造成员方法的时候把值添加进去

    * @author dell
    *
    */

    public class Tank {
    private int x, y;
    private int w = Constant.TW;
    private int h = Constant.TH;
    private int speed = Constant.TSPEED;
    private boolean good = true;
    private boolean tL = false, tR = false, tU = false, tD = false;
    private boolean live = true;
    private int life = 100;
    private BloodBar bb=new BloodBar();
    public int getTimes() {
    return times;
    }

    public void setTimes(int times) {
    this.times = times;
    }

    private int times=0;
    public int getLife() {
    return life;
    }

    public void setLife(int life) {
    this.life = life;
    }

    private int oldX, oldY;
    MyFrame mf;

    public enum Direction {
    L, LU, LD, R, RU, RD, U, D, STOP
    };

    private Direction ptDir = Direction.D;// 定义一个炮筒的方向,默认朝上
    private Direction direction = Direction.STOP;
    private static Random r = new Random();
    private int step = r.nextInt(15) + 5;

    public Tank(int x, int y, boolean good) {
    this.x = x;
    this.y = y;
    this.oldX = x;
    this.oldY = y;
    this.good = good;
    }

    public Tank(int x, int y, boolean good, Direction direction, MyFrame mf) {
    this(x, y, good);
    this.direction = direction;
    this.mf = mf;
    }

    public void draw(Graphics g) {
    if (!live)
    return;
    if (good) {
    Color c = g.getColor();
    g.setColor(Color.white);
    g.fillOval(x, y, Constant.TW, Constant.TH);
    g.setColor(c);
    bb.draw(g);
    } else {
    Color c = g.getColor();
    g.setColor(Color.red);
    g.fillOval(x, y, Constant.TW, Constant.TH);
    g.setColor(c);
    }
    switch (ptDir) {
    case L:
    g.drawLine(x + w / 2, y + h / 2, x, y + h / 2);
    break;
    case LU:
    g.drawLine(x + w / 2, y + h / 2, x, y);
    break;
    case LD:
    g.drawLine(x + w / 2, y + h / 2, x, y + h);
    break;
    case R:
    g.drawLine(x + w / 2, y + h / 2, x + w, y + h / 2);
    break;
    case RU:
    g.drawLine(x + w / 2, y + h / 2, x + w, y);
    break;
    case RD:
    g.drawLine(x + w / 2, y + h / 2, x + w, y + h);
    break;
    case U:
    g.drawLine(x + w / 2, y + h / 2, x + w / 2, y);
    break;
    case D:
    g.drawLine(x + w / 2, y + h / 2, x + w / 2, y + h);
    break;
    }
    move();
    }
    public void reStart(){
    while(!this.isLive()){
    this.x=Constant.FWID - Constant.TW;
    this.y=Constant.FHEI- Constant.TH;
    this.setLive(true);
    this.setLife(100);
    times++;
    }
    }
    public Missile fire() {
    if (!this.live)
    return null;
    Missile m1 = null;
    if (this.good) {
    m1 = new Missile(x + w / 2 - Constant.MissileW / 2, y + h / 2
    - Constant.MissileH / 2, ptDir, true, mf);
    mf.missiles.add(m1);
    } else {
    m1 = new Missile(x + w / 2 - Constant.MissileW / 2, y + h / 2
    - Constant.MissileH / 2, ptDir, false, mf);
    mf.missiles.add(m1);
    }
    return m1;
    }

    public Missile fire(Direction dir) {// 在此方法中为子弹初始化
    if (!this.isLive())
    return null;
    int x1 = this.x + Constant.TW / 2 - Constant.MissileW / 2;
    int y1 = this.y + Constant.TH / 2 - Constant.MissileH / 2;
    Missile m = new Missile(x1, y1, dir, this.good, this.mf);
    mf.missiles.add(m);
    return m;
    }

    public void superFire() {
    Direction[] dirs = direction.values();
    for (int i = 0; i < dirs.length - 1; i++) {
    fire(dirs[i]);
    }
    }

    public void keypressed(KeyEvent e) {
    switch (e.getKeyCode()) {
    case KeyEvent.VK_LEFT:
    tL = true;
    break;
    case KeyEvent.VK_RIGHT:
    tR = true;
    break;
    case KeyEvent.VK_UP:
    tU = true;
    break;
    case KeyEvent.VK_DOWN:
    tD = true;
    break;
    }
    chooseDirection();
    }

    public void keyReleased(KeyEvent e) {
    switch (e.getKeyCode()) {
    case KeyEvent.VK_CONTROL:
    fire();
    break;
    case KeyEvent.VK_SHIFT:
    superFire();
    break;
    case KeyEvent.VK_LEFT:
    tL = false;
    break;
    case KeyEvent.VK_RIGHT:
    tR = false;
    break;
    case KeyEvent.VK_UP:
    tU = false;
    break;
    case KeyEvent.VK_DOWN:
    tD = false;
    break;
    case KeyEvent.VK_F1:
    reStart();
    break;
    }
    chooseDirection();
    }

    // 判断坦克的方向
    public void chooseDirection() {
    if (tL && !tR && !tU && !tD)
    direction = Direction.L;
    if (tL && !tR && tU && !tD)
    direction = Direction.LU;
    if (tL && !tR && !tU && tD)
    direction = Direction.LD;
    if (!tL && tR && !tU && !tD)
    direction = Direction.R;
    if (!tL && tR && tU && !tD)
    direction = Direction.RU;
    if (!tL && tR && !tU && tD)
    direction = Direction.RD;
    if (!tL && !tR && tU && !tD)
    direction = Direction.U;
    if (!tL && !tR && !tU && tD)
    direction = Direction.D;
    if (!tL && !tR && !tU && !tD)
    direction = Direction.STOP;
    }

    public void move() {
    oldX = x;
    oldY = y;
    switch (direction) {
    case L:
    x = x - speed;
    break;
    case LU:
    x = x - speed;
    y = y - speed;
    break;
    case LD:
    x = x - speed;
    y = y + speed;
    break;
    case R:
    x = x + speed;
    break;
    case RU:
    x = x + speed;
    y = y - speed;
    break;
    case RD:
    x = x + speed;
    y = y + speed;
    break;
    case U:
    y = y - speed;
    break;
    case D:
    y = y + speed;
    break;
    }
    if (direction != Direction.STOP) {
    ptDir = direction;
    }
    if (x < 0)
    x = 0;// 使坦克不会出界
    if (y < 25)
    y = 25;
    if (x > Constant.FWID - Constant.TW)
    x = Constant.FWID - Constant.TW;
    if (y > Constant.FHEI - Constant.TH)
    y = Constant.FHEI - Constant.TH;
    if (!good) {
    Direction[] dir = Direction.values();
    if (step == 0) {
    step = r.nextInt(15) + 5;
    int randomNum = r.nextInt(dir.length);// 在不超过数组长度的条件下产生随机数
    direction = dir[randomNum];
    fire();
    }
    step--;
    }

    }

    public boolean hitWall(greatWall gw) {
    if (this.isLive() && this.getRect().intersects(gw.getRect())) {
    stay();
    return true;
    }
    return false;
    }

    public Rectangle getRect() {
    Rectangle rt = new Rectangle(x, y, Constant.TW, Constant.TH);
    return rt;
    }

    public boolean pengTank(List<Tank> enemyTanks) {
    for (int i = 0; i < enemyTanks.size(); i++) {
    Tank enemyTank = enemyTanks.get(i);
    if (this != enemyTank) {
    if (this.isLive() && enemyTank.isLive()
    && this.getRect().intersects(enemyTank.getRect())) {
    stay();
    return true;
    }
    }
    }
    return false;
    }

    private class BloodBar {
    public void draw(Graphics g) {
    Color c = g.getColor();
    g.setColor(Color.green);
    g.drawRect(x, y - 10, Constant.TW, 10);
    g.fillRect(x, y - 10, Constant.TW * life / 100, 10);
    }
    }

    private void stay() {
    x = oldX;
    y = oldY;
    }

    public boolean isLive() {
    return live;
    }

    public boolean isGood() {
    return good;
    }

    public void setGood(boolean good) {
    this.good = good;
    }

    public void setLive(boolean live) {
    this.live = live;
    }

    }

    package Mygame;

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

    import MyFrame.MyFrame;

    public class TankGame extends MyFrame{

    public static void main(String[] args) {
    TankGame t=new TankGame();
    t.launchFrame();
    }
    }

    界面如下:

    出现问题及解决办法:

    问题:使用enum(枚举)类型时,eclipse无法识别,显示错误。

    解决方法:窗口-->首选项-->java-->编译器

    将编译器一致性级别调至1.5以上,如图:

     实验总结:

    实验完成有难度,在代码确定的情况下,测试也有一定的困难,在重构的操作中,类多容易给重构对象的判断造成干扰,在TDD测试中,没有完整的实行代码块,将很难调试通过。要相对代码进行重新编译。

    结对同学:20135222胡御风

    blog地址:http://www.cnblogs.com/huyufeng/ 

  • 相关阅读:
    SpringMVC拦截器使用
    JavaCORBA
    Mybatis各语句高级用法(未完待续)
    [译文]C# Heap(ing) Vs Stack(ing) in .NET: Part II
    [译文]C# Heap(ing) Vs Stack(ing) in .NET: Part I
    iBatis连接MySQL时的注意事项
    MyBatis入门
    属性(property) VS 数据成员(field)
    [译文]C# Heap(ing) Vs Stack(ing) in .NET: Part III
    LINQ To Objects
  • 原文地址:https://www.cnblogs.com/chuishi/p/4553385.html
Copyright © 2011-2022 走看看