北京电子科技学院(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/

java第三次实验的更多相关文章

  1. 20155210 潘滢昊 Java第三次实验

    Java第三次实验 实验内容 在IDEA中使用工具(Code->Reformate Code)把代码重新格式化 在码云上把自己的学习搭档加入自己的项目中,确认搭档的项目加入自己后,下载搭档实验二 ...

  2. 南京邮电大学java第三次实验报告

    实 验 报 告 ( 2017 / 2018学年 第2学期) 课程名称 JAVA语言程序设计 实验名称 Java集成开发环境的安装与使用. Java变量.表达式与控制结构 实验时间 2018 年 4 月 ...

  3. Java第三次实验敏捷开发与XP实验

    实验三-1 1.实验要求: 实验三 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA 参考 http: ...

  4. java第三次实验报告

    北京电子科技学院(BESTI) 实验报告 课程: Java程序设计 班级: 1352 姓名: 池彬宁 学号: 20135212 成绩: 指导教师: 娄嘉鹏 实验日期: 2015.6.3 实验密级: 无 ...

  5. 20135208 JAVA第三次实验

    课程:Java实验   班级:201352     姓名:贺邦  学号:20135208 成绩:             指导教师:娄佳鹏   实验日期:15.06.03 实验密级:         ...

  6. 20165210 Java第三次实验报告

    20165210 实验二 敏捷开发与XP实践 一.敏捷开发与XP实践-1 实验要求: http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替 ...

  7. Java第三次实验要求

    实验三 类与对象(一) 一. 实验目的 1. 掌握类与对象的基本概念: 2. 掌握类的声明.创建与用法: 3. 掌握类的构造方法的定义与用法 4. 掌握类的成员变量.成员方法的定义与用法: 5. 理解 ...

  8. 20145320《Java程序设计》第三次实验报告

    20145320<Java程序设计>第三次实验报告 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1453 指导教师:娄嘉鹏 实验日期:2016.04.22 15: ...

  9. 实验三《Java面向对象程序设计》实验报告

    20162308 实验三<Java面向对象程序设计>实验报告 实验内容 XP基础 XP核心实践 IDEA工具学习 密码学算法基础 实验步骤 (一)Refactor/Reformat使用 p ...

随机推荐

  1. dpkg安装失败解决过程

      终于好了.搞到转钟3点都没搞定,耽误不少时间. 执行sudo port install dpkg 报错如下Error: org.macports.build for port gmp return ...

  2. 记一次Apache Carbondata PR的经历

     前言 前段时间有幸接触到Apache Carbondata,试用过程中发现了一个小小的问题,并且又很快的定位到了问题.然后在社区群里反映了下,负责人问愿不愿意提个JIRA,PR,然后我在没有任何开源 ...

  3. Hadoop(1)-CentOS6.8的安装,配置和克隆

    准备工作 150G及以上的硬盘空间(因为要搭建3个系统组成的集群),cpu尽量i7-7xxx标压以上,内存16G及以上 自行搜索,下载,安装VMWare 准备CentOS6.8的镜像文件 注意:安装虚 ...

  4. JavaEE笔记(六)

    实现Action的几种方法1. implements Action2. extends ActionSupport3. 也可以不继承任何父类不实现任何借口 #当一个类有多个方法 package com ...

  5. EDB*Plus的client_encoding问题

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页 [作者 高健@博客园  luckyjackga ...

  6. PosgreSQL 9.0 High Performance中文版瑕疵

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL杂记页     回到顶级页面:PostgreSQL索引页 发表此文不是为了吐槽,而是为了防止更多的受害者出现啊,拿到书后 ...

  7. 【转载】D3DXMatrixLookAtLH视图变换函数详解

    原文:D3DXMatrixLookAtLH视图变换函数详解 /*D3DXMatrixLookAtLH函数返回的是世界->视图变换矩阵. 视图坐标系和局部坐标系是一样的,都是世界坐标系转换为指定的 ...

  8. sublime常用方法

    1.如何打开一个文件夹? project----->Add Folder to Project 2.如何同一个窗口下进行分屏操作? 使用快捷键:shift+Alt+2 3.如何使html代码进行 ...

  9. SSIS 控制流和数据流

    在SSIS的体系结构中,Package是SSIS的最重要的部分,从本质上来讲,Package是一个有序地执行任务的单元.Package的核心是控制流(Control Flow),用于协调包中所有组件的 ...

  10. paramiko 简单的使用

    感觉自己操作服务器还要用xshell,麻烦很多,于是呢就去google,找到了paramiko. 使用这个模块还是很简单的, 我们链接服务器,只需要导入 SSHClient,AutoAddPolicy ...