用户:MashKJo/1.12.2模组开发教程/10.BlockState系统及Forge BlockStates V1模型格式
和Item一样,我们和世界中的方块进行交互时,实际上交互的也并非Block本身,而是它的某个方块状态(BlockState)。BlockState的存在允许我们为世界中实际存在的某个方块附加一些属性:一个或多个IProperty<T extends Comparable<T>>。方块状态对象都是接口IBlockState的实例。
很多教程都会说ItemStack和IBlockState是相似的,其实不然:一来,ItemStack的使用是随建随用,而IBlockState甚至一定程度上遵循享元设计模式;二来,同一种物品对应的ItemStack有无数多种,而同一种方块的方块状态种类是可以被穷尽的。
原版中有很多多BlockState的方块,如熔炉就有8种方块状态——朝向有4种,工作状态2种:熄灭/燃烧,乘起来就是8种。
在本节教程中,笔者将完整地讲述创建一个多BlockState方块的全过程。
给方块附加属性
首先我们需要在对应的方块类中添加相应的静态IProperty<T extends Comparable<T>>字段。实际上我们完全不需要重新实现这个接口,用Minecraft提供的一系列默认实现就好了。默认实现一共有3种:PropertyInteger、PropertyBool和PropertyEnum<T extends Enum & IStringSerializable>。顾名思义,它们分别用于描述整型、布尔型和枚举型的属性。值得注意的是,它们的构造方法都是protected修饰的,那么我们如何构造它们呢?答案是利用它们的静态方法create。
三种IProperty的默认实现类的对象的构造,都要求一个String参数,用于设定该属性的名称,这个参数只能由小写字母和下划线组成,我们会在方块的blockstates JSON文件中看到它的身影。对于PropertyInteger,我们还需要指定该属性的最大值和最小值。对于PropertyEnum,我们需要一个实现了IStringSerializable接口的枚举类(这个接口只有一个方法:String getName()
,也是为blockstates JSON文件服务的);该属性会默认接受该枚举类的所有枚举值,但我们也可以显式指定哪些值会被允许,如传入一个数组或Collection,甚至一个Predicate,都是可以的。