User Tools

Site Tools


zh_cn:tutorial:blockstate

给一个方块状态

Minecraft中的每种类型的区方块都由一个单独的“区块”实例表示。 这样就无法仅通过更改方块实例的状态来更改特定方块的状态, 因为该类型的其他所有方块都会受到影响! 但是,如果您想给出一个单一的方块状态,以便它可以根据某些条件改变,该怎么办? 这就是BlockState的目的。 假设我们希望方块的硬度通常为0.5,但是如果我们在尝试破坏它之前右键单击它, 它会变得更硬并获得“2”的硬度。

首先,我们定义方块的boolean属性-是否很难(小心不要导入错误的BooleanProperty!):

public class MyBlock extends Block {
    public static final BooleanProperty HARDENED = BooleanProperty.of("hardened");
}

然后,我们需要通过OverrideappendProperties来注册属性:

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(getStateManager().getDefaultState().with(HARDENED, false));
    }
 
}

(要设置多个属性,请链接with()调用)

现在,要设置属性,我们需要调用world.setBlockState()

(用方块的实例替换MyBlocks.MY_BLOCK_INSTANCE

public class MyBlock extends Block {
    [...]
    @Override
    public boolean activate(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult blockHitResult) {
        world.setBlockState(pos, MyBlocks.MY_BLOCK_INSTANCE.getDefaultState().with(HARDENED, true));
        return true;
    }
}

并使用该属性,我们称为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;
    }
}

为方块状态添加模型

您还可以根据状态更改方块的纹理和模型。 这是通过称为Blockstate 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会不高兴。 -分配给变体的对象可以添加各种属性,例如旋转或纹理处理。请查看下面的链接的“模型”页面,以获取有关可以添加哪些属性的更多文档。 所有变体都必须包含“模型”属性。 -始终在模型属性中传递“模型”属性。在这种情况下,游戏将查看位置``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``的布尔属性,并且您想根据模型是否发光以及是否经过硬化来更改模型,则需要四个变体:harded off和发光,硬化并发光,硬化并发光,并硬化并发光。如果需要,可以将同一模型分配给多个变体。

这只是对块状态JSON的简单介绍。 Minecraft Wiki中记录了有关块状态和模型JSON的所有技巧,以及在香草中使用这些功能的示例。祝你好运!

关于性能的注意事项

游戏开始时会注册一个块的每个可能状态。 这意味着,如果您具有14个布尔属性,则该块具有2 ^ 14 = 16384个不同的状态,并且已注册2 ^ 14个状态。 因此,块不应包含太多的块状态属性。 相反,应该主要为视觉保留块状态, Block Entities应该用于更高级的状态。

zh_cn/tutorial/blockstate.txt · Last modified: 2019/12/19 03:12 by lightcolour