葫芦兄弟java7723_课内资源

1. 效果展示

葫芦娃胜利:

6e9adcc2548e84730355fceaa5e37b2f.png

2. 项目介绍

2.1 玩法

新游戏:设置好葫芦娃阵形和妖怪阵形(菜单栏)之后点击菜单栏开始->新游戏,选择游戏记录的输出文件

回放:可以按”L”也可以点击菜单栏开始->回放,打开并读取游戏记录的输出文件

2.2 游戏设计

2.2.1 画面介绍

整个画面分成5部分:菜单栏、中间主战场、左右两边的状态栏、底部的消息面板

人物的战斗相关属性有: 血量、攻击力、防御力、移动速度、攻击范围、发射子弹的速度、子弹的移动速度

左右两边的状态栏显示人物的剩余血量比例、攻击力、防御力

底部消息面板播报人物阵亡消息以及游戏提示

2.2.3 人物介绍

左边是葫芦娃7兄弟(取消了老爷爷),右边是妖怪和一群小喽啰

两边的人物数量均等,都是7只

人物移动速度、子弹发射速度、子弹移动速度实际上是相应的行为发生后距离下一次该行为发生经过的时间(ms)

为了游戏平衡,人物的某些属性较厉害的同时也能其他属性会弱一点

人物名称

血量

攻击力

防御力

移动速度

攻击范围

子弹发射速度

子弹移动速度

子弹颜色

解释

老大

200

50

20

1000

3

500

200

RED

老大力大无穷,所以攻击力较高

老二

150

30

30

500

10

1000

800

ORANGE

老二是千里眼顺风耳,攻击范围较大

老三

200

20

40

1000

6

500

500

YELLOW

老三是铜头铁臂,防御力较高

老四

100

40

20

1000

4

1000

500

GREEN

老四能喷火,攻击力较高

老五

100

30

30

1000

8

1000

800

CYAN

老五能喷水,综合表现一般

老六

100

30

40

1000

6

1000

500

BLUE

老六能隐身不容易被发现,防御力较高

老七

100

20

30

500

6

500

500

PURPLE

老七只有宝葫芦,攻击表现一般,但走得快

蝎子精

300

40

30

1000

6

800

800

DARKBLUE

蝎子精是大BOSS,综合能力较强

蛇精

200

30

40

1000

8

1000

500

BLACK

蛇精的综合能力也较强

蜈蚣精

200

30

35

1000

5

1000

500

BROWN

作为妖界第三,实力还行

蛤蟆精

200

30

25

1500

5

1000

1000

DARKVIOLET

除了血量,其他属性是来打酱油的

2.2.3 战斗过程

游戏开始后,每个人物寻找附近的敌人,如果不在自己的攻击范围内,则向敌人方向移动,如果在攻击范围内,则向敌人发射子弹。移动的过程带有一定的随机性(试想一下如果敌人在右方,而上方、右方、下方都被己方占领了,如果没有随机性,则人物一直试图向右走,然而是走不通的)。人物受到攻击时,计算血量损失,更新两侧面板的血量。如果小于等于0,则人物死亡,在1000ms内渐渐消失,不留下尸体。两侧状态栏显示人物的灰度图表明人物已死。当其中一方完全死亡时,战场画面被清空,只留下胜利画面和确定按钮。在战斗过程中或者回放过程中,无法选择人物阵形;选择人物阵形之前不能开始新游戏。

2.2.4 伤害计算

若敌人攻击力>自己防御力:

血量 -= (敌人攻击力-自己防御力)

否则根据自己防御力与敌人攻击力的差距梯度减少血量

可以避免死循环的情况(敌人攻击力<=自己防御力&&自己攻击力<=敌人防御力)

2.3 代码结构

2.3.1 包目录annotation

being

formation

gui

thread

test(测试代码)

2.3.2 annotation

显然是放注释的,我写了一个Author注释,标明作者。

2.3.3 being

所有的生物类型、子弹、生物的阵营属性(好与坏)、战斗接口。

每种生物都有其所属阵营(即Property),继承自Good类的生物的Property为GOOD,继承自Bad类的生物的Property为BAD。生物能够创建子弹(Creature有一个Bullet的ArrayList存放创建的子弹),生物能够战斗(Creature实现了Battle接口,实际上Battle接口就是创建子弹),生物能够移动。

每个葫芦娃设计成不同的类,因为不同的葫芦娃的战斗属性不同,并且可以方便以后添加各自独特的技能。

UML类图:

48e764884cceffa7e764e05a394a99d0.png

2.3.4 formation

阵形包,所有的阵形继承自Formation。除了阵形相关的类还有一个Position类,如下所示:

0f95a7f4d7d2b631ec3714fed8ee0259.png

每个Being人手一份全局的Positions(二维,数量为战场格子行数*列数),因此生物可以观察到各个位置上其他生物的情况,可以移动到其他格子上。多个生物线程争夺位置,必须要对Position的setbeing方法加锁。

2.3.5 gui

入口Main类、World类、战场格子Cell类(放置在中间的GridPane面板上)、左右状态栏类、底部消息面板类。Main类初始化整体画面,World类创建生物,并且要根据玩家的行为(新游戏或者回放)来启动不同的线程。

2.3.6 thread

这个包是最重要的一个包,生物线程的活动、GUI界面的刷新都由它完成。

UML类图:

ca7ae678d215cb664bf75033750f29d8.png

BattleThread

负责创建所有的生物线程,启动定时器,传递用户打开的文件路径给UIFileThread,定时运行UIFileThread,以及当UIFileThread运行完后结束所有线程、关闭资源、初始化所有生物(循环利用生物对象,节约资源)。它自己本身并没有继承Thread或者实现 Runnable接口。

CreatureThread

每个生物一个生物线程,将生物对象装入生物线程里。生物线程做决定,指挥生物定位敌人、移动、创建子弹。生物线程并不是FX线程,因此生物线程只负责创建出子弹把子弹放在一个list里,等待UI线程取出子弹创建子弹线程并播放子弹移动动画。

UIFileThread

继承自Thread,当游戏还没有结束,刷新UI界面(根据生物此时的Position位置将生物图片放置到相应的战场Cell格子上),更新左右状态栏,更新底部消息面板,当生物死亡时播放消失的动画,取出生物创建的子弹,启动子弹线程并播放子弹运行的动画。当游戏结束时,关闭定时器、调用BattleThread中的结束线程、关闭资源、初始化生物的方法。并且要将整个过程记录在文件中。文件记录格式:txt文件,每一行记录当前所有活着的生物或者刚刚死去的生物的代号、位置、血量、子弹list中的子弹及子弹的目标列,每个生物用空格隔开。如 R:3,4,200,b5 O:5,6,die 表示老大在(3,4)位置,发射了一个子弹(从(3,4)到(3,5)),老二在(5,6)位置刚刚死去。

因为这个线程是由BattleThread启动定时器定时调用的,而非FX线程不 能刷新界面,所以在定时器中UIFileThread并不直接作为任务执行,而是经过其他任务A来执行Platform.runLater(UIFileThread)从而来执行此线程,所以定时器实际是对任务A定时,这就可能造成多线程的不安全问题,所以UIFileThread的run方法里面要加锁。

BulletThread

因为子弹的运动是播放javaFX动画,子弹并不占据战场中的Cell,而是直接放置在GridPane面板的

相应位置上,所以子弹线程需要每隔一定时间(其所属的生物中的子弹移动速度)计算当前的位置以确定当前位置上是否有敌人从而对敌人造成伤害。

我将子弹的运动设计成动画而不是像生物一样占据Position一格一格地前进(子弹是不占据Position的),是为了子弹的运动能够更加流畅,而且最重要的问题是如果不是这样那么当子弹前行时碰到障碍(敌人或者友军或者另一个子弹)那么它该怎么办?一个位置只能同时被一个物体占据。

ReplayThread

与BattleThread类似,负责启动定时器定时执行ReplayUIThread,结束时关闭资源等。不过不需要

创建生物线程。同样它本身没有继承Thread或者实现Runnable接口。

ReplayUIThread

当输入文件流不为空时,解析每一行生物的状态并更新UI。与UIFileThread一样,run方法里需要加锁。

2.3.7 test

测试包放了测试文件,我创建了一行10个Position,10个除了Position[10]不带其他参数的Being(将Being从abstract class改成 class,以及一个只有Position[]的构造方法,这个构造方法是为了测试而创建的,只用于测试不能用于程序主体),让10个Being在(0,10)之间随机选择一个数index,占位Position[index],如果没能成功占位则位置设置为-1。最后输出成功占位的生物所在的位置是否有相同的。

3. 设计思想

3.1 封装

多数的属性都是包可见的,不能直接被包外的类访问,向外界提供获取方法。

生物线程不直接将生物移动位置,而是调用生物的moveto()等方法指挥生物

3.2 继承

所有生物继承自Creature,Creature又继承自Being。Creature又被其他类继承。而Creature类和Being类实现了所有通用方法,代码复用程度高。

所有阵形继承自Formation。

3.3 多态

Formation申明了设置阵形的方法,设置不同的阵形调用各自不同的设置方法。

3.4 异常处理

创建文件流、线程睡眠。

3.5 集合

主要是ArrayList,很多地方都用到了,例如生物将创建好的子弹放在ArrayList中。

3.6 泛型

Cell中可以放置的物体、Position中放置的物体采用了泛型 \。

3.7 注解

每个包中主要的类添加了Author注解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值