# 1. 开发环境
- IntelliJ IDEA 2018.2.5 (Ultimate Edition)
- Java 版本 1.8.0_181
- Maven 3.6.0
# 2. 项目简介
- HuluWa World 是一个葫芦娃与妖精对战的游戏。游戏开始前玩家可以布置阵型,游戏开始后葫芦娃与妖精自动进行战斗。
- 除了战斗功能外,还支持录像回看。
# 3. 运行截图
![](https://www.writebug.com/myres/static/uploads/2021/11/1/f1ffd614f17a5b6118ec39d5f44f1729.writebug)
# 4. 运行说明
- 使用 Maven 对项目进行编译,打包。
- 运行 target 目录下 HuluWa-1.0-SNAPSHOT.jar。
- 进入游戏后,可以通过两侧按钮和对单位鼠标拖拽的方式进行排兵布阵。
- 按 SPACE 键开始游戏。按 R 键重置游戏状态。按 L 键选择录像进行回放。
- 上一盘游戏的录像文件保存在游戏程序同一目录下。新的游戏会覆盖上一次游戏的录像。
# 5. 项目详情
## 5.1 目录
- /replay 存放了录像,以供回放使用。
- /ScreenShots 存放了 README.md 使用到的图片
- /src/main/java 项目源代码
- /src/main/resources 项目资源文件
- /src/test/java 单元测试代码
## 5.2 代码结构
### 5.2.1 gui
- class Main 是整个程序的入口。
- class GameController 是 JavaFX 框架,使用 FXML Scene Builder 工具的一个控制器。整个处理程序的各种外部事件处理函数、画面刷新函数等都在该类里。
- class GUIRefresher 用于定时进行刷新画面。
### 5.2.2 package space
- class Tile 是二维平面的基本组成单位,生物体能够放置在 Tile 上。Tile 具有一系列接口可以判断该 Tile 对象上是否有生物体、将该 Tile 对象上的生物体移除、在该 Tile 上放置一个生物体等。
```java
public class Tile<T extends Creature> {
private int coordinateX;
private int coordinateY;
private T creatureStandOnTile;
public void removeCreatureStandOnTile() {
/*...*/
}
public void setCreatureStandOnTile(T x) {
/*...*/
}
public boolean isEmpty() {
/*...*/
}
public Creature getCreature() {
/*...*/
}
}
```
- class TwoDimensionSpace 实现了一个由 Tile 组成的二维平面。利用 Tile 类提供的接口,可以对 TwoDimensionSpace 对象的某一个坐标进行操作。
```java
public class TwoDimensionSpace<T extends Creature> {
private Tile<T> space[][];
private int size;
private int sizeM;
private int sizeN;
public boolean isEmpty(int x, int y) {
/*...*/
}
public boolean isCreatureOn(int x, int y) {
/*...*/
}
public Creature getCreature(int x, int y) {
/*...*/
}
/*...*/
}
```
- class Coordinate 具有两个成员,记录 X 轴坐标和 Y 轴坐标,用于生物体寻找路径等需要用到二元数对的地方记录坐标。
### 5.2.3 package creature
- class Creature 是所有生物体的基类,能够在二维平面上行走战斗。并且实现了 Runnable 接口。
```java
public class Creature implements Runnable{
/*...*/
}
```
- class Demon 继承于 Creature。
- class HuluWa 继承于 Creature。
- class Grandpa 继承于 Creature。
- class Snake 继承于 Demon。
- class Scorpion 继承于 Demon。
![](https://www.writebug.com/myres/static/uploads/2021/11/1/03fccc29da70616885eae1ad832ff9d1.writebug)
### 5.2.4 package group
- interface Group 是一个公共接口,实现该接口的类应能够进行排列阵型。
```java
public interface Group {
public void generateFormation(Formation formation, TwoDimensionSpace space, int x, int y, int direction);
public void initialize();
}
```
- class HuluBrothers 实现了 Group 接口,并由一组 HuluWa 对象和一个 Grandpa 对象组合而成,是游戏中的葫芦娃阵营。
- class Monsters 实现了 Group 接口,并由一组 Demon 对象组合而成,是游戏中的妖怪阵营。
![](https://www.writebug.com/myres/static/uploads/2021/11/1/c923682b8ef088e146ac6e176585b36c.writebug)
### 5.2.5 package Formation
- abstract class Formation 是一个抽象类,并具有一个抽象接口用于排列阵型。
```java
public abstract class Formation {
public abstract void generateFormation(TwoDimensionSpace space, Creature beings[], Creature ob, int x, int y, int direction);
}
```
- class ChangsheFormation 继承了 Formation 类,具体实现了长蛇阵法。
- class FangmenFormation 继承了 Formation 类,具体实现了长蛇阵法。
- class FengshiFormation 继承了 Formation 类,具体实现了长蛇阵法。
- class HengeFormation 继承了 Formation 类,具体实现了长蛇阵法。
- class HeyiFormation 继承了 Formation 类,具体实现了长蛇阵法。
- class YanhangeFormation 继承了 Formation 类,具体实现了长蛇阵法。
- class YanyueFormation 继承了 Formation 类,具体实现了长蛇阵法。
- class YulinFormation 继承了 Formation 类,具体实现了长蛇阵法。
![](https://www.writebug.com/myres/static/uploads/2021/11/1/c4ced56addc8dac954713e627a408897.writebug)
### 5.2.6 package battle
class BattleField 该类由一个二维空间、葫芦娃阵营和妖怪阵营组合而成。包含了葫芦娃游戏所需的所有元素。
### 5.2.7 package replay
- class Replay 实现了 Runnable 接口,void run()函数中实现了录像回看的功能。
- class ReplayWriter 提供了一个多个 Creature 线程共同写文件的解决方案。
### 5.2.8 package navigate
- class Navigation 具有一个方法 getNavigate,游戏中生物体通过该方法能够绕过障碍物,规划出一条能够到达目的位置的路线。
```java
public class Navigation {
public HashMap<Integer, Integer> getNavigate(Creature c, TwoDimensionSpace space) {
/*...*/
}
```
### 5.2.9 package color
enum COLOR 是一个枚举类型,class HuluWa 的颜色属性需要使用。
### 5.2.10 package sort
- interface Sort 是一个公共接口,具有一个排序方法,用于对一组葫芦娃进行排序。
```java
public interface Sort {
public void sort(HuluWa[] brothers);
}
```
- class HuluWaColorSort 实现了 Sort 接口,基于葫芦娃的颜色进行排序。
- class HuluWaPrioritySort 实现了 Sort 接口,基于葫芦娃的排行进行排序。
![](https://www.writebug.com/myres/static/uploads/2021/11/1/76f0574c3d6c13951f03d7662a9699e0.writebug)
### 5.2.11 package annotation
@interface AuthorAnno 是一个生命期至 running time 的一个类型注解,可以标识一个类的作者和版本。
# 6. 功能实现
## 6.1 阵型排列
- 用户可以通过程序界面两侧的按钮布置阵型。用户点击按钮后通过按钮的触发事件处理函数,将生物体排列成相应的阵型。
- 用户也可以通过鼠标拖拽排列生物体。首先定义了一个 DragDetect 事件,当拖拽开始时,通过坐标转换获得二维空间对应位置的生物体(可能为 null)。然后定义了一个 Drag 事件,在鼠标拖拽过程中不断将生物体移动到鼠标当前坐标对应在二维空间的位置,并刷新画面形成生物体被鼠标拖拽的效果。
- DragDetect 和 Drag 事件的处理函数在游戏进行中都被将被禁用,以免干扰正常的游戏。
```java
@FXML private void canvasDragDetect(MouseEvent event) {
if (!fighting) {
return;
}
int x = (int)event.getX();
int y = (int)event.getY();
x = x / 72;
y = y / 72;
if (battle.space.getCreature(y, x) != null) {
selected = battle.space.getCreature(y, x);
}
}
@FXML private void canvasDrag(MouseEvent event) {
if (!fighting) {
return;
}
int x = (int)event.getX();
int y = (int)event.getY();
x = x / 72;
y = y / 72;
if (selected != null) {
selected.moveTo(battle.space, y, x);
}
display();
}
```
## 6.2 战斗功能
- GameControll