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可能非常简单。它看起来像这样: <code JavaScript resources/assets/mymod/blockstates/my_block.json> { “variants”: { “”: { “model”: “mymod:block/my_block” } } } </code> Let's break this simple example down. There are a couple important parts to this JSON: - The “variants” block will be where all possible variations for your blockstate go. We'll explore variants more in a little. - A variant named “” will apply to every permutation of a blockstate. If you have a “” variant, you shouldn't have any other variants in the JSON, or Minecraft will get upset. - The object assigned to the “” variant can have various properties added to it like rotation or texture manipulation. Check out the linked Model page below for more documentation on what properties can be added. All variants must contain a “model” property. - The “model” property is always passed an ID of a model. In this case, the game will look at the location src/main/resources/assets/mymod/models/block/my_block.json. The ID here can be anything. It doesn't need to be the same as your block's ID, but if you only have one variant, it probably should. Block models have their own setup, which is documented very well on the Minecraft wiki page linked below. You can either write the JSON by hand or use a program like Blockbench to generate it more easily. If you do want to have different models for each blockstate, you'd want to add multiple variants. For the same src/main/resources/assets/mymod/blockstates/my_block.json location we used above, your could would probably look like such: <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> In this JSON, there are two variants, one for each possibility of the HARDENED property we defined above. Since we gave the property the string name of hardened in the Java, that's what we use here. Booleans only have two states, but if you use properties based on integers or enums, you'll have more variants. Variants are based on possible permutations of the properties added to your block. A property can be totally ignored in the blockstate JSON if you want, like in the first blockstate JSON where we ignored the hardened property, but if you want to include a property in one variant, it must be included in all variants. If mymod:my_block also had a boolean property called glowing'', and you wanted to change the model based on whether it was glowing and based on whether it was hardened, you would need four variants: hardened off and glowing off, hardened on and glowing off, hardened off and glowing on, and hardened on and glowing on. The same model can be assigned to multiple variants if you need it to be.

This is only a simple introduction to blockstate JSONs. All of the tricks you can do with blockstate and model JSONs are documented on the Minecraft wiki, along with examples of how the features are used in vanilla. Best of luck!

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.1576724326.txt.gz · Last modified: 2019/12/19 02:58 by lightcolour