八、进度条与自定义合成表
写在前面
本来我想将进度放入本章节当中,但无奈进度牵扯到json
文件,估计我又要叽叽喳喳讲一堆json
,出于人最基本的性格,这章节暂且不讲。
进度条
说起进度条,打个最简单的比方:凋零、末影龙。当你去攻击这些Boss时,你的游戏上方都会出现一个红色的长条,显示着Boss的血量,它就是进度条。
有人说,这不应该是血量条吗?可以,它也是血量条,但它的真正功能远远不止是显示怪物的血量。
某个任务的完成进度,倒计时、忍耐值、愤怒值都可以用进度条来完成。
自定义合成表
用工作台去合成各种各样的东西,这再也熟悉不过了,不过我们需要再发明一种新的合成方式,这就需要用到插件中的某个类。
哎呀,这两个太简单了,我直接合并成一个章节。
1.进度条
- 进度条为BossBar类
首先,我们需要创建一个进度条createBossBar
。
@NotNull
public static KeyedBossBar createBossBar(@NotNull NamespacedKey key, @Nullable String title, @NotNull BarColor color, @NotNull BarStyle style, @NotNull BarFlag... flags) {
return server.createBossBar(key, title, color, style, flags);
}
key
:你可以理解为是这个进度条的身份证(key
)和容器一样,都有一个key
title
:进度条的标题color
:进度条的颜色,只能从BLUE
、GREEN
、PINK
、PURPLE
、RED
、WHITE
、YELLOW
中选择style
:进度条的样式,只能从SOLID
、SEGMENTED_6
、SEGMENTED_10
、SEGMENTED_12
、SEGMENTED_20
中选择flags
:进度条的附加属性列表(可选,可添加不止一个),只能从CREATE_FOG
、DARKEN_SKY
、PLAY_BOSS_MUSIC
中选择
常量 | 说明 |
---|---|
SOLID | 将血条设置为 1 个部分 |
SEGMENTED_6 | 将血条设置为 6 个部分 |
SEGMENTED_10 | 将血条设置为 10 个部分 |
SEGMENTED_12 | 将血条设置为 12 个部分 |
SEGMENTED_20 | 将血条设置为 20 个部分 |
CREATE_FOG | 末影龙的血条属性,告诉客户端播放打末影龙时候的BGM |
DARKEN_SKY | 凋零血条的属性(战斗时天空会变暗) |
PLAY_BOSS_MUSIC | 在血条所在的世界创建一个迷雾 |
BossBar bossBar = Bukkit.createBossBar(
new NamespacedKey(PluginMain.instance, "MyFirstBossBar"),
"哈哈哈",
BarColor.PINK,
BarStyle.SOLID,
BarFlag.DARKEN_SKY
);
如此,在上面的代码中,创建了一个标题为“哈哈哈”、颜色为粉色、将进度条分成1个部分(整体)、出现时将天空变暗的一个进度条。
结束了吗?当然没有,我们需要将进度条应用到玩家身上:
//将进度条应用到输入命令的玩家上
bossBar.addPlayer((Player)sender);
同样,也可以移除某个玩家:
bossBar.removePlayer((Player)sender);
效果:
现在是白天,当创建完了进度条后,天空明显变暗,并且上方出现了一个“哈哈哈”的进度条。
但是现在的进度是空的,需要加一点东西才行。我们可以更改进度条的进度。
bossBar.setProgress(0.5);//50%,如果是进度100%就是1
如果你不希望看到进度条,可以使用setVisible
以设置进度条的可见性。如果你希望销毁这个进度条,可以使用Bukkit.removeBossBar
以取消注册,注意:传参需是你想要移除的进度条的Namespacedkey
,也就是开头所说的进度条的身份证,不然你要这个身份证干嘛?
2.自定义合成表
是不是觉得下界合金锭太难获得了?
它其实就是一个铁锭,外面抹上火药罢了,从此解放双手……
不信谣,不传谣!但我们真的可以通过插件来使每一个谣言成真!
2.1.有序配方
- 使用
ShapedRecipe
类自定义一个合成表
public ShapedRecipe(@NotNull NamespacedKey key, @NotNull ItemStack result) {
...
}
NamespacedKey
在进度条已经说过了,形象说是一个身份证。
result
表示这个合成表合成的物品是什么。
ShapedRecipe recipe = new ShapedRecipe(new NamespacedKey(PluginMain.instance, "a_shaped_rec"), new ItemStack(Material.NETHERITE_INGOT));
如上,创建了一个叫a_shaped_rec
的合成表,合成的是下界合金锭。但我们该怎么告诉合成配方是什么呢?
先用一把小木剑举例:
如上图,一把木剑需要使用一根木棍,两个橡木方块。设木棍为 a a a,橡木方块为 b b b,即可得到下面简化的合成表(加号代表空):
+
b
+
+b+
+b+
+
b
+
+b+
+b+
+
a
+
+a+
+a+
将这个合成表进行降维打击并剔除空格,就变成了:
b b a b \; b \; a bba
看到这就明白了,我们只需传入这些代替后的一维合成表就可以了。
recipe = recipe.shape("bbb","bab","bbb");//传入合成表
注意!每当ShapedRecipe
设置完后,其调用的方法最后都会返回一个ShapedRecipe
,所以我们需要重新赋值,否则这个设置是无效的
然后,我们需要告诉合成表这些字母(或其他)代替的是什么物品。
//b代表火药,a代表铁锭
recipe = recipe.setIngredient('b',Material.GUNPOWDER).setIngredient('a',Material.IRON_INGOT);
然后将其注册到Bukkit当中:
Bukkit.addRecipe(recipe);
此时,又一个谣言就成真了。
但!你是否注意过:做火把时,只需有木头和煤炭(木炭)就行了,而不要求它们摆放的位置,熔炉则要老老实实地摆放。
又或者,在第三章我们讲解物品堆时,我们可以更改一个物品(如钻石)的名称、介绍等,更改后的物品虽然还是钻石,却不能和原来没有更改的物品重叠放置。这些物品在有些合成中,比如更改过名称的钻石,它在合成中是不会被看做钻石的,所以无法合成,而有些则可以合成。
很奇怪?其实Bukkit提供了两种setIngredient
方法:
@NotNull
public ShapedRecipe setIngredient(char key, @NotNull MaterialData ingredient) {
...
}
@NotNull
public ShapedRecipe setIngredient(char key, @NotNull RecipeChoice ingredient) {
...
}
两者唯一的区别就是后一个参数的类型不同。第一种方法只需要是这个物品就行了,无论名称和介绍。第二种方法必须是物品相同、名称相同、介绍相同等等,必须是一模一样的物品。
2.2.无序配方
除上面的有序配方之外,还有ShapelessRecipe
类,也就是无序的配方,如做火把一样,数量齐了就行。
//创建一个无序配方
ShapelessRecipe recipe = new ShapelessRecipe(new NamespacedKey(PluginMain.instance, "a_shapeless_rec"), new ItemStack(Material.NETHERITE_INGOT));
与ShapedRecipe
有些不同的是,我们不用告诉Bukkit配方的摆放如何,直接传入需要什么物品,需要多少个即可。
//需要8个火药,1个铁锭组成下界合金锭
recipe = recipe.addIngredient(8, Material.GUNPOWDER).addIngredient(1, Material.IRON_INGOT);
最后依然不要忘了注册到Bukkit当中去。
Bukkit.addRecipe(recipe);
注意!一定要记住,只要我们创建了自定义合成表,在插件卸载时一定要清空!
public static PluginMain instance;
public void onDisable() {
instance = null;
Bukkit.resetRecipes();
say(parse("&4插件已卸载!&6作者:BeginTu"));
}
切记啦!服务器崩了不要怪我!
End.结尾
大家是否有这些疑问(勤思考,好奇心不会害死猫):
Q1:这些功能,我在单人游戏上用指令也能完成啊。
A1:没错!插件的大部分功能都能用指令完成。
Q2:我似乎是在单人游戏上玩多人游戏。
A2:了解CS架构的都懂。
Q3:Q2基础上,自定义的合成表为什么能够被合成?它在单人游戏上不应该是无法合成的吗?