User Tools

Site Tools


zh_cn:tutorial:blockstate

This is an old revision of the document!


给一个方块状态

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``位置,您可能看起来像这样: <code JavaScript resources/assets/mymod/blockstates/my_block.json> { “variants”: { “hardened=false”: { “model”: “mymod:block/my_block” }, “hardened=true”: { “model”: “mymod:block/my_block_hardened” } } } </code> 在此JSON中,有两种变体,一种针对我们上面定义的HARDENED属性的每种可能性。由于我们在Java中为属性指定了字符串hardened,因此我们在这里使用它。布尔值只有两种状态,但是如果您使用基于整数或枚举的属性,则会有更多的变体。 变体基于添加到块中的属性的可能排列。如果需要,可以在块状态JSON中完全忽略属性,例如在第一个块状态JSON中我们忽略了``hardened``属性,但如果要在一个变体中包含属性,则必须将其包含在中所有变体。如果``mymod:my_block``还具有一个称为``glowing``的布尔属性,并且您想根据模型是否发光以及是否经过硬化来更改模型,则需要四个变体:harded off和发光,硬化并发光,硬化并发光,并硬化并发光。如果需要,可以将同一模型分配给多个变体。 这只是对块状态JSON的简单介绍。 Minecraft Wiki中记录了有关块状态和模型JSON的所有技巧,以及在香草中使用这些功能的示例。祝你好运! ==== A note about performance ==== Every possible state of a block is registered at the start of the game. This means that if you have 14 boolean properties, the block has 2^14 = 16384 different states and 2^14 states are registered. For this reason blocks should not contain too many blockstate properties. Rather, blockstates should be mostly reserved for visuals, and Block Entities should be used for more advanced state.

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