第一个 Java 小游戏(改错)

OOP h07

请确认已经完成 h06

本作业给出了一部分代码,但是这些代码实现有错误,要么无法编译通过,要么存在错误

不许修改现有类的名字,不许修改现有的继承关系,不许增加新的类,可以在现在代码基础上改动

使得作业代码能够完成本作业要求的测试

0x00 分析

本次作业目的为找出程序中的错误。

0x01 Test

末尾多了一个 }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package com.huawei.classroom.student.h07;

/**
* @author super
*/
public class Test {

public Test() {
// TODO Auto-generated constructor stub
}

public static void main(String[] args) {
// TODO Auto-generated method stub
// 某一款游戏,其主要角色如下:
// 游戏中每个对象有当前 x,y坐标,坐标值 取值范围为整数。
// 非建筑物可以通过move(dx,dy)来移动坐标值,dx,dy表示x轴,y轴增量, 取值范围为整数。
// 对象A攻击B的时候,要满足两个对象之间直线距离小于等于A的攻击范围,否则攻击无效(被攻击方不减健康值)
// 任何对象有getHealth() 方法,返回当前生命值,如果已经死亡则返回 <=0的一个数字
// 任何对象有isDestroyed() 方法,如果生命值<=0则true,否则false

// GameBase 玩家基地 初始生命值500,无攻击力,初始x,y值在创建时指定
// Barrack 兵营,可以训练出步枪兵、 RPG兵、军犬,初始生命值100,无攻击力,初始x,y值在创建时指定
// Rifle soldier 步枪兵 初始生命值50(对战 军犬除外),攻击力 5(对战军犬可以一次击毙军犬),攻击范围5,初始x,y值就是兵营的x,y
// RPG soldier 火箭兵 初始生命值50(对战 军犬除外),攻击力 10 ,攻击范围10,初始x,y值就是兵营的x,y
// Dog 军犬 ,初始生命值50,攻击力5(对战人类时候一口毙命),攻击范围5,初始x,y值就是兵营的x,y
// 此外还要能通过Soldier.getLivingSoldierCount/getDeadedSoldierCount
// 统计现在有多少个活着的和死去的士兵数量
// 请遵循以上游戏规则,并根据如下测试代码设计代码
// 作业批改的时候,方法可能不同组合
// 例如让一个物体移动,超出或者进入攻击范围,判断是否攻击有效
// 让一个物体制造出来以后,不移动,然后另一个物体攻击,判断该物体是否使用了默认的x,y

////////////////h07作业内容 /////////////////////////////////
// 本作业给出了一部分代码,但是这些代码实现有错误,要么无法编译通过,要么存在错误
// 不许修改现有类的名字,不许修改现有的继承关系,不许增加新的类,可以在现在代码基础上改动
// 使得作业代码能够完成本作业要求的测试

GameBase gameBase = GameBase.createGameBase(10, 10);

if (gameBase.getHealth() == 500) {
System.out.println("ok1");
}
Barrack barrack = (Barrack) gameBase.building(EnumObjectType.barrack, 20, 20);
if (barrack.getHealth() == 100) {
System.out.println("ok2");
}
// traing 训练出新的士兵或者狗
RifleSoldier rifleSoldier1 = (RifleSoldier) barrack.traing(EnumObjectType.rifleSoldier);
if (rifleSoldier1.getHealth() == 50) {
System.out.println("ok3");
}
RPGSoldier rPGSoldier1 = (RPGSoldier) barrack.traing(EnumObjectType.RPGSoldier);
if (rPGSoldier1.getHealth() == 50) {
System.out.println("ok4");
}
Dog dog1 = (Dog) barrack.traing(EnumObjectType.dog);
if (dog1.getHealth() == 50) {
System.out.println("ok5");
}

// 移动的是坐标值增量
rPGSoldier1.move(10, 10);
rifleSoldier1.attack(rPGSoldier1);
// 攻击无效,距离太远,health
if (rPGSoldier1.getHealth() == 50) {
System.out.println("ok6");
}

rifleSoldier1.move(7, 6);
rifleSoldier1.attack(rPGSoldier1);
if (rPGSoldier1.getHealth() == 45) {
System.out.println("ok7");
}

dog1.attack(rPGSoldier1);
if (rPGSoldier1.getHealth() == 45) {
System.out.println("ok8");
}

dog1.move(10, 10);
rPGSoldier1.attack(dog1);
if (dog1.getHealth() == 40) {
System.out.println("ok9");
}

dog1.attack(rPGSoldier1);
dog1.attack(rPGSoldier1);
if (rPGSoldier1.isDestroyed() ) {
System.out.println("ok10");
}

rifleSoldier1.attack(dog1);
if (dog1.isDestroyed() ) {
System.out.println("ok11");
}
if (Soldier.getDeadedSoldierCount() == 1) {
System.out.println("ok12");
}
if (Soldier.getLivingSoldierCount() == 1) {
System.out.println("ok13");
}

if (gameBase instanceof GameObject) {
System.out.println("ok14");
}

if (rifleSoldier1 instanceof GameObject) {
System.out.println("ok15");
}
if (barrack instanceof Building) {
System.out.println("ok16");
}

}



}

0x02 GameObject

  1. defaultStrength 未使用,应删除。
  2. 构造方法中应指明 this
  3. attack 应首先判断是否死亡。
  4. attack 应在攻击范围小于攻击距离时停止。
  5. 不应该通过类实例访问静态成员。
  6. changeHealthdead 均未使用,应删除。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package com.huawei.classroom.student.h07;

/**
* @author super
*/
public abstract class GameObject {
private int range;
private int x;
private int strength;

private int y;

private int health = 0;

public GameObject(int x, int y) {
this.x = x;
this.y = y;
}

public GameObject() {

}

public void attack(GameObject obj) {
if (obj.isDestroyed()) {
return;
}
int dx = this.x - obj.x;
int dy = this.y - obj.y;
double dis = Math.pow(dx * dx + dy * dy, 0.5);
if (this.range < dis) {
return;
}

obj.health = obj.health - this.strength;
}

public void attack(Soldier soldier) {
if (soldier.isDestroyed()) {
return;
}
int dx = this.x - soldier.getX();
int dy = this.y - soldier.getY();
double dis = Math.pow(dx * dx + dy * dy, 0.5);
if (this.range < dis) {
return;
}
soldier.setHealth(soldier.getHealth() - this.strength);
if (soldier.getHealth() <= 0) {
Soldier.livingSoldierCount--;
Soldier.deadedSoldierCount++;
}
}

public int getHealth() {
return health;
}
public int getRange() {
return range;
}
public int getStrength() {
return strength;
}

public int getX() {
return x;
}

public int getY() {
return y;
}

public boolean isDestroyed() {
return health <= 0;
}

public void move(int dx, int dy) {
this.x = this.x + dx;
this.y = this.y + dy;
}

public void setHealth(int health) {
this.health = health;
}

public void setRange(int range) {
this.range = range;
}

public void setStrength(int strength) {
this.strength = strength;
}

public void setX(int x) {
this.x = x;
}

public void setY(int y) {
this.y = y;
}
}

0x03 GameBase

  1. 缺少构造方法。
  2. createGameBase 中需要传递参数。
  3. setHealth 参数类型应为 int,下面 l00 应为 100
  4. return 应使用英文半角分号。
  5. building 缺少返回值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.huawei.classroom.student.h07;


/**
* @author super
*/
public class GameBase extends GameObject {
public GameBase(int x, int y) {
super(x, y);
}

public static GameBase createGameBase(int x, int y) {
GameBase gameBase = new GameBase(x, y);
gameBase.setHealth(500);
return gameBase;
}

public Building building(EnumObjectType type, int x, int y) {
if (type == EnumObjectType.barrack) {
Barrack barrack = new Barrack(x, y);
barrack.setHealth(100);
return barrack;
} else {
return null;
}

}
}

0x04 Building

需要调用父类构造方法传递参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.huawei.classroom.student.h07;

/**
* @author super
*/
public class Building extends GameObject {

public Building( int x ,int y) {
super(x, y);

}

}

0x05 Barrack

  1. 需要调用父类构造方法传递参数,设置生命值。
  2. traing 缺少 new
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.huawei.classroom.student.h07;


/**
* @author super
*/
public class Barrack extends Building {

public Barrack(int x, int y) {
super(x, y);
setHealth(100);
// TODO Auto-generated constructor stub
}

public GameObject traing(EnumObjectType type) {
GameObject gameObject = null;

if (type == EnumObjectType.rifleSoldier) {
gameObject = new RifleSoldier();
gameObject.setHealth(50);
gameObject.setStrength(5);
gameObject.setRange(5);
} else if (type == EnumObjectType.RPGSoldier) {
gameObject = new RPGSoldier();
gameObject.setHealth(50);
gameObject.setStrength(10);
gameObject.setRange(10);
} else if (type == EnumObjectType.dog) {
gameObject = new Dog();
gameObject.setHealth(50);
gameObject.setStrength(5);
gameObject.setRange(5);
}
gameObject.setX(this.getX());
gameObject.setY(this.getY());
return gameObject;
}

}

0x06 Soldier

Soldier 拼写错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.huawei.classroom.student.h07;

/**
* @author super
*/
public abstract class Soldier extends GameObject {

public static int livingSoldierCount = 0;
public static int deadedSoldierCount = 0;

public Soldier() {

livingSoldierCount++;
// TODO Auto-generated constructor stub
}

public static int getLivingSoldierCount() {
return livingSoldierCount;
}

public static int getDeadedSoldierCount() {
return deadedSoldierCount;
}

}

0x07 RifleSoldier&RPGSoldier&Dog

RifleSoldierRPGSoldier 的构造方法应调用父类无参数构造方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.huawei.classroom.student.h07;

/**
* @author super
*/
public class RifleSoldier extends Soldier {



public RifleSoldier() {
super();
//super( Param.SOLDIER_HEALTH,Param.SOLDIER_RIFLE_STRENGTH);
// TODO Auto-generated constructor stub
}

@Override
public void attack(GameObject obj) {
int dx = this.getX() - obj.getX();
int dy = this.getY() - obj.getY();
double dis = Math.pow(dx * dx + dy * dy, 0.5);
if (this.getRange() > dis) {
return;
}
if (obj instanceof Dog) {
obj.setHealth(0);
} else {
obj.setHealth(obj.getHealth() - this.getStrength());
}
}


}
1
2
3
4
5
6
7
8
9
10
11
package com.huawei.classroom.student.h07;

/**
* @author super
*/
public class RPGSoldier extends Soldier {
public RPGSoldier() {
super();
}

}

Dog 需修改 attack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.huawei.classroom.student.h07;

/**
* @author super
*/
public class Dog extends GameObject {

public Dog() {

// super( Param.DOG_HEALTH,Param.DOG_STRENGTH);
// TODO Auto-generated constructor stub
}

@Override
public void attack(Soldier soldier) {
if (soldier.isDestroyed()) {
return;
}
int dx = this.getX() - soldier.getX();
int dy = this.getY() - soldier.getY();
double dis = Math.pow(dx * dx + dy * dy, 0.5);
if (this.getRange() < dis) {
return;
}
soldier.setHealth(0);
if (soldier.getHealth() <= 0) {
Soldier.livingSoldierCount--;
Soldier.deadedSoldierCount++;
}
}

}