方块状态

在之前我们已经稍微地提及了BlockState,但是我们的第一个方块显然是没有状态的,这一节我们将以黑曜石魔方举例来创建一个带有状态的方块。

首先创建一个叫做ObsidianRubikCube的类,内容如下:

public class ObsidianRubikCube extends Block {
    private static IntegerProperty STATE = IntegerProperty.create("face", 0, 1);

    public ObsidianRubikCube() {
        super(Properties.create(Material.ROCK).hardnessAndResistance(5));
        this.setDefaultState(this.stateContainer.getBaseState().with(STATE, 1));
    }

    @Override
    protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
        builder.add(STATE);
        super.fillStateContainer(builder);
    }
}

这里有三个和之前我创建方块不一样的地方,首先就是:

private static IntegerProperty STATE = IntegerProperty.create("face", 0, 1);

在这句话里,我们创建了一个新的方块状态,正如IntegerProperty这个名字暗示的那样,这个是一个整数类型的方块状态,除了IntegerProperty原版还实现了BooleanPropertyEnumProperty,并且原版还在BlockStateProperties类下实现了很多预设的方块状态,可以按需使用。如果这些类型都不满足你的需求,你还可以继承Property自己创建一个新的种类的方块状态。

IntegerProperty.create("face", 0, 1)

的意思是,这个方块状态的名字叫做face,最小值是0,最大值是1

@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
  builder.add(STATE);
  super.fillStateContainer(builder);
}

然后我们在fillStateContainer里调用传入的builder变量中的add方法给我的方块添加了一个状态。

最后,我们在构造方法里设置了默认状态(可以不用设置)。

this.setDefaultState(this.stateContainer.getBaseState().with(STATE, 1));

注册方块

public static RegistryObject<Block> obsidianRubikCube = BLOCKS.register("obsidian_rubik_cube", () -> {
  return new ObsidianRubikCube();
});

注册物品

public static RegistryObject<Item> obsidianRubikCube = ITEMS.register("obsidian_rubik_cube", () -> {
  return new BlockItem(BlockRegistry.obsidianRubikCube.get(), new Item.Properties().group(ModGroup.itemGroup));
});

接下来在blockstates文件夹下创建你和方块注册名相同的json文件,我们创建obsidian_rubik_cube.json,内容如下:

{
  "variants": {
    "face=0": { "model": "neutrino:block/obsidian_rubik_cube_model_0" },
    "face=1": { "model": "neutrino:block/obsidian_rubik_cube_model_1" }
  }
}

可以看到,我们在这里为不同的face值指定了不同的模型,分别是obsidian_rubik_cube_model_0obsidian_rubik_cube_model_1。请注意,如果你要定义多个blockstate的值,请用半角逗号隔开,中间不要有空格。具体的要求也请参考Wiki中关于模型的章节。

然后我们在models/block下创建obsidian_rubik_cube_model_0.jsonobsidian_rubik_cube_model_1.json这两个模型文件。

obsidian_rubik_cube_model_0.json:

{
  "parent": "block/cube_all",
  "textures": {
    "all": "neutrino:block/obsidian_rubik_cube_texture_0"
  }
}

obsidian_rubik_cube_model_1.json:

{
  "parent": "block/cube_all",
  "textures": {
    "all": "neutrino:block/obsidian_rubik_cube_texture_1"
  }
}

可以看见它分别加载了两个不同的材质。

然后添加材质。

obsidian_rubik_cube_texture_0.png

obsidian_rubik_cube_texture_0

obsidian_rubik_cube_texture_1.png

obsidian_rubik_cube_texture_1

最后给我们的物品模型obsidian_rubik_cube添加内容:

{
  "parent": "neutrino:block/obsidian_rubik_cube_model_1"
}

D2627490-F744-4BD9-B06C-09FC7CCB166B

7B934D2C-8596-49FA-A5FE-05709ABFFBF2

可以看到,随着我们用debug stick改变了方块的状态,方块的模型和材质也发生了改变。

源代码