This is an old revision of the document!
给予方块状态
Minecraft中的每种类型的方块都由一个单独的Block
实例表示。这样就无法仅通过更改Block
实例的状态来更改特定方块的状态,因为该类型的其他所有方块都会受到影响!但是,如果您想给出一个单一的方块状态,以便它可以根据某些条件改变,该怎么办?这就是BlockState
的目的。假设我们希望方块的硬度通常为0.5
,但是如果我们在尝试破坏它之前右键单击它,它会变得更坚硬并获得2
的硬度。
首先,我们定义方块的boolean属性-是否坚硬(小心不要导入错误的BooleanProperty!):
public class MyBlock extends Block { public static final BooleanProperty HARDENED = BooleanProperty.of("hardened"); }
然后,我们需要通过覆盖appendProperties
来注册属性:
public class MyBlock extends Block { [...] @Override protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) { stateManager.add(HARDENED); } }
然后,我们需要在方块构造器中设置属性的默认状态:
public class MyBlock extends Block { [...] public MyBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(HARDENED, false)); } }
(要设置多个属性,请通过调用with()
来连接)
现在,要设置属性,我们需要调用world.setBlockState()
:
(用你的方块的实例替换MyBlocks.MY_BLOCK_INSTANCE
)
public class MyBlock extends Block { [...] @Override public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { world.setBlockState(pos, state.with(HARDENED, true)); return ActionResult.SUCCESS; } }
并使用该属性,我们称为blockState.get(<我们的属性名称>)
:
public class MyBlock extends Block { [...] @Override public float getHardness(BlockState blockState, BlockView blockView, BlockPos pos) { boolean hardened = blockState.get(HARDENED); if(hardened) return 2.0f; else return 0.5f; } }
为方块状态添加模型
你可能还需要使得纹理和模型根据状态修改。这是通过叫做方块模型JSON的JSON文件完成的。所有的方块都需要一个方块模型JSON,无论是有多个状态还是只有一个,但是JSON的内容可以简单也可以复杂。如果需要根据模型改变方块纹理,你将会需要多个模型。
假设您将MyBlock
的实例注册到IDmymod:my_block
。Minecraft将在src/main/resources/assets/mymod/blockstates/my_block.json
位置查找文件以加载状态。如果您不希望方块在模型随状态改变,则方块状态JSON可能非常简单,就像这样:
- resources/assets/mymod/blockstates/my_block.json
{ "variants": { "": { "model": "mymod:block/my_block" } } }
让我们分解一下这个简单的例子。JSON有几个重要的部分:
- “variants”
方块将成为您的方块状态所有可能的变化形式。我们将稍作探讨。
- 名为“”
的变种将应用于每个方块状态的排列。如果你有“”
变种,则JSON中不应包含任何其他变体,否则Minecraft会不高兴。
- 分配给“”
变种的对象可以添加各种属性,例如旋转或纹理操作。请查看下面的链接的“模型”页面,以获取有关可以添加哪些属性的更多文档。所有变种都必须包含“模型”属性。
- “model”
属性总是传递模型的ID。在这种情况下,游戏将查看位置src/mainresources/assets/mymod/models/block/my_block.json
。这里的ID可以是任何东西,不需要与方块的ID相同,但是如果只有一个变种,则应当要相同。方块模型具有自己的设置,在下面链接的Minecraft Wiki页面上有很好的记录。您可以手动编写JSON,也可以使用Blockbench之类的程序更轻松地生成它。
如果确实想要为每个方块状态使用不同的模型,则需要添加多个变种。对于我们上面使用的同一个src/main/resources/assets/mymod/ blockstates/my_block.json
位置,你可能需要这样子:
- resources/assets/mymod/blockstates/my_block.json
{ "variants": { "hardened=false": { "model": "mymod:block/my_block" }, "hardened=true": { "model": "mymod:block/my_block_hardened" } } }
在此JSON中,有两个变种,一种针对我们上面定义的HARDENED
属性的每种可能性。由于我们在Java中为属性指定了字符串hardened
,因此我们在这里使用它。布尔值只有两种状态,但是如果您使用基于整数或枚举的属性,则会有更多的变种。
变种基于添加到方块中的属性的可能排列。如果需要,可以在方块状态JSON中完全忽略属性,例如在第一个块状态JSON中我们忽略了hardened
属性,但如果要在一个变种中包含属性,则必须将其包含在所有变种。如果mymod:my_block
还具有一个称为glowing
的布尔属性,并且您想根据模型是否发光以及是否经过硬化来更改模型,则需要四个变种:硬化发光,硬化不发光,不硬化但发光,不硬化不发光。如果需要,可以将同一模型分配给多个变种。
这只是对方块状态JSON的简单介绍。Minecraft Wiki中记录了有关方块状态和模型JSON的所有技巧,以及在原版游戏中使用这些功能的示例。祝你好运!
关于性能的注意事项
游戏开始时会注册方块的所有可能状态。这意味着,如果具有14个布尔属性,则该方块具有2 ^ 14 = 16384个不同的状态,并且会注册这2 ^ 14个状态。因此,方块不应包含太多的方块状态属性。相反,方块状态应主要保留用于视觉效果,需要使用更高级的状态应使用方块实体。