3,441
个编辑
MCBBS Wiki欢迎您共同参与编辑!在参与编辑之前请先阅读Wiki方针。
如果在编辑的过程中遇到了什么问题,可以去讨论板提问。
为了您能够无阻碍地参与编辑 未验证/绑定过邮箱的用户,请尽快绑定/验证。
MCBBS Wiki GitHub群组已上线!
您可以在回声洞中发表吐槽!
服务器状态监控。点击进入
本站由MCBBS用户自行搭建,与MCBBS及东银河系漫游指南(北京)科技有限公司没有从属关系。点此了解 MCBBS Wiki 不是什么>>
无编辑摘要 |
|||
| 第5行: | 第5行: | ||
原版中有很多多BlockState的方块,如熔炉有4种方块状态——朝向有4种:水平方向的东、南、西、北,而实际上熔炉的燃烧/熄灭这一属性不是通过IProperty控制的,而是通过构造方法中的一个boolean参数控制的——即熄灭的熔炉和燃烧的熔炉实际上不是同一个Block,而它们各自有4种方块状态。 | 原版中有很多多BlockState的方块,如熔炉有4种方块状态——朝向有4种:水平方向的东、南、西、北,而实际上熔炉的燃烧/熄灭这一属性不是通过IProperty控制的,而是通过构造方法中的一个boolean参数控制的——即熄灭的熔炉和燃烧的熔炉实际上不是同一个Block,而它们各自有4种方块状态。 | ||
在本节教程中,作者将完整地讲述创建一个多BlockState方块的全过程。 | |||
== 给方块附加属性 == | == 给方块附加属性 == | ||
| 第39行: | 第39行: | ||
那么,工作是不是已经做完了呢?当然没有,我们毕竟还要写相应的JSON文件嘛,不过读者可能会觉得,仅仅是为了测试的话,没必要立刻就写JSON文件,可以直接顶着紫黑块的压力,按F3查看它的属性值!好的,这么做确实可以,然而注册完方块,runClient之后读者会发现代码根本跑不起来,会崩溃——且抛出一个IllegalArgumentException:"Don't know how to convert [state] back into data..."。 | 那么,工作是不是已经做完了呢?当然没有,我们毕竟还要写相应的JSON文件嘛,不过读者可能会觉得,仅仅是为了测试的话,没必要立刻就写JSON文件,可以直接顶着紫黑块的压力,按F3查看它的属性值!好的,这么做确实可以,然而注册完方块,runClient之后读者会发现代码根本跑不起来,会崩溃——且抛出一个IllegalArgumentException:"Don't know how to convert [state] back into data..."。 | ||
好的,所以作者还需要讲一个很重要的概念:方块的meta值。是不是很眼熟?ItemStack就有meta值啊。只是在ItemStack中,meta值兼任损害值和类型序数两个概念,由hasSubtypes字段控制它的具体含义。但对于方块而言,没损害值这一说,所以方块的meta值就代表它的一个类型。这么说,方块的meta岂不是和它的BlockState作用重合了?是这样的,在Minecraft 1.8版本之前,BlockState系统还不存在,那时候方块被附加上不同属性后得到的“状态”就是用方块的meta值来描述的——玩家在世界中和方块交互时,以及Minecraft内部机制序列化、反序列化地图时,用的都是方块的meta值。但BlockState系统加入后,meta值便只被用于序列化、反序列化存档地图了。显然我们需要给一个方块的所有BlockState都各自指定一个meta值,否则Minecraft根本就不知道如何序列化或反序列化这种多BlockState方块。我们覆写<code>Block#getStateFromMeta</code>和<code>Block#getMetaFromState</code>这两个方法,即可,runClient后,游戏便能正常进入了。 | |||
和ItemStack不同,方块的meta值只能是0 - 15这个范围内的整数——最多只有16种可能;而在99%的情况下,所有BlockState和所有meta值之间的关系都是一一对应的,因此'''通常情况下''',一个方块的BlockState最多只有16种。但也有例外——比如栅栏、红石粉、火焰这些方块,它们实际上有着成百上千种BlockState,那么这是如何做到的呢?它们实际上都只指定了部分BlockState的meta值,同时覆写了<code>Block#getActualState</code>方法,该方法能根据周围的方块的方块状态,计算出它本身该是什么方块,这一部分算出来的BlockState实际上是不参与序列化和反序列化的。这个手段实际上很有局限性,为何?能这么做的方块,它的特点也很明确:它本身的BlockState确实会随着它周围的方块的BlockState的变化而变化,那对于箱子这种能存储物品(实际上是ItemStack)的方块呢?就没辙了,毕竟你总不可能不打开箱子,根据它周围的方块状态就确定它里面装的到底都有啥吧(笑),而且因为ItemStack本身有附加NBT,因此可以这么说,同一种物品的ItemStack有无限种可能。所以,指望着BlockState系统来完成这件事是没辙了。 | 和ItemStack不同,方块的meta值只能是0 - 15这个范围内的整数——最多只有16种可能;而在99%的情况下,所有BlockState和所有meta值之间的关系都是一一对应的,因此'''通常情况下''',一个方块的BlockState最多只有16种。但也有例外——比如栅栏、红石粉、火焰这些方块,它们实际上有着成百上千种BlockState,那么这是如何做到的呢?它们实际上都只指定了部分BlockState的meta值,同时覆写了<code>Block#getActualState</code>方法,该方法能根据周围的方块的方块状态,计算出它本身该是什么方块,这一部分算出来的BlockState实际上是不参与序列化和反序列化的。这个手段实际上很有局限性,为何?能这么做的方块,它的特点也很明确:它本身的BlockState确实会随着它周围的方块的BlockState的变化而变化,那对于箱子这种能存储物品(实际上是ItemStack)的方块呢?就没辙了,毕竟你总不可能不打开箱子,根据它周围的方块状态就确定它里面装的到底都有啥吧(笑),而且因为ItemStack本身有附加NBT,因此可以这么说,同一种物品的ItemStack有无限种可能。所以,指望着BlockState系统来完成这件事是没辙了。 | ||