本篇教程的视频
本篇教程的源代码
GitHub地址:
自定义方块类
后面的教程我们将讲到树,以及它们的世界生成
不过,在有树之前,得先有各种木头,所以这里我们先来注册各种木头
但是嘞,话又说回来了,我们还得先写一些自定义的方块类
ModRotatedPillarBlock
我们先创建这个类,它是继承自RotatedPillarBlock的
1 2 3 4 5
| public class ModRotatedPillarBlock extends RotatedPillarBlock { public ModRotatedPillarBlock(Properties pProperties) { super(pProperties); } }
|
这个类会在注册原木和木头时调用
接下来我们重写一些方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Override public boolean isFlammable(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { return true; }
@Override public int getFlammability(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { return 5; }
@Override public int getFireSpreadSpeed(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { return 5; }
|
这是定义我们方块的燃烧相关的属性的
isFlammable:是否可燃
getFlammability:获取易燃性
getFireSpreadSpeed:获取燃烧传播速度
因为原版相关的燃烧属性被硬编码在了FireBlock里面,我们自己添加的方块是没有这些属性的,不过IForge提供了额外的拓展方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static void bootStrap() { FireBlock fireblock = (FireBlock)Blocks.FIRE; fireblock.setFlammable(Blocks.OAK_PLANKS, 5, 20); ... fireblock.setFlammable(Blocks.OAK_LOG, 5, 5); ... fireblock.setFlammable(Blocks.STRIPPED_OAK_LOG, 5, 5); ... fireblock.setFlammable(Blocks.OAK_WOOD, 5, 5); ... fireblock.setFlammable(Blocks.OAK_LEAVES, 30, 60); ... }
|
当然,原版这里的方法顺序是传播速度、易燃性
另外我们还需要重写一个getToolModifiedState方法
1 2 3 4 5 6 7 8 9 10 11
| @Override public @Nullable BlockState getToolModifiedState(BlockState state, UseOnContext context, ToolAction toolAction, boolean simulate) { if (context.getItemInHand().getItem() instanceof AxeItem) { if (state.is(ModBlocks.ICE_ETHER_LOG.get())) { return ModBlocks.STRIPPED_ICE_ETHER_LOG.get().defaultBlockState().setValue(AXIS, state.getValue(AXIS)); } else if (state.is(ModBlocks.ICE_ETHER_WOOD.get())) { return ModBlocks.STRIPPED_ICE_ETHER_WOOD.get().defaultBlockState().setValue(AXIS, state.getValue(AXIS)); } } return super.getToolModifiedState(state, context, toolAction, simulate); }
|
这个方法是当我们使用斧头右键没被削皮的原木或者木头时,执行并返回相应的去皮原木或者木头
因为原版的映射也是被硬编码在了AxeItem类里面
当然,这里的方块我们还没写
ModPlankBlock
同样的,我们来创建一个木板方块类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class ModPlankBlock extends Block { public ModPlankBlock(Properties pProperties) { super(pProperties); }
@Override public boolean isFlammable(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { return true; }
@Override public int getFlammability(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { return 20; }
@Override public int getFireSpreadSpeed(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { return 5; } }
|
ModLeavesBlock
以及一个树叶方块类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class ModLeavesBlock extends LeavesBlock { public ModLeavesBlock(Properties pProperties) { super(pProperties); }
@Override public boolean isFlammable(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { return true; }
@Override public int getFlammability(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { return 60; }
@Override public int getFireSpreadSpeed(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { return 30; } }
|
注册方块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public static final RegistryObject<Block> ICE_ETHER_LOG = registerBlocks("ice_ether_log", () -> new ModRotatedPillarBlock(BlockBehaviour.Properties.copy(Blocks.OAK_LOG)));
public static final RegistryObject<Block> ICE_ETHER_WOOD = registerBlocks("ice_ether_wood", () -> new ModRotatedPillarBlock(BlockBehaviour.Properties.copy(Blocks.OAK_LOG)));
public static final RegistryObject<Block> STRIPPED_ICE_ETHER_LOG = registerBlocks("stripped_ice_ether_log", () -> new ModRotatedPillarBlock(BlockBehaviour.Properties.copy(Blocks.OAK_LOG)));
public static final RegistryObject<Block> STRIPPED_ICE_ETHER_WOOD = registerBlocks("stripped_ice_ether_wood", () -> new ModRotatedPillarBlock(BlockBehaviour.Properties.copy(Blocks.OAK_LOG)));
public static final RegistryObject<Block> ICE_ETHER_LEAVES = registerBlocks("ice_ether_leaves", () -> new ModLeavesBlock(BlockBehaviour.Properties.copy(Blocks.OAK_LEAVES)));
public static final RegistryObject<Block> ICE_ETHER_PLANKS = registerBlocks("ice_ether_planks", () -> new ModPlankBlock(BlockBehaviour.Properties.copy(Blocks.OAK_PLANKS)));
|
原木和木头以及它们各自对应的去皮状态,都是实例化RotatedPillarBlock,里面的内容倒是差不多
树叶我们也一并注册了,实例化LeavesBlock
木板简单,实例化普通的方块
记得将这些方块加到物品栏里面去
1 2 3 4 5 6
| pOutput.accept(ModBlocks.ICE_ETHER_LOG.get()); pOutput.accept(ModBlocks.ICE_ETHER_WOOD.get()); pOutput.accept(ModBlocks.STRIPPED_ICE_ETHER_LOG.get()); pOutput.accept(ModBlocks.STRIPPED_ICE_ETHER_WOOD.get()); pOutput.accept(ModBlocks.ICE_ETHER_LEAVES.get()); pOutput.accept(ModBlocks.ICE_ETHER_PLANKS.get());
|
数据文件
常规的,我们还是用数据生成来生成数据文件
战利品列表
1 2 3 4 5 6
| dropSelf(ModBlocks.ICE_ETHER_LOG.get()); dropSelf(ModBlocks.STRIPPED_ICE_ETHER_LOG.get()); dropSelf(ModBlocks.ICE_ETHER_WOOD.get()); dropSelf(ModBlocks.STRIPPED_ICE_ETHER_WOOD.get()); dropSelf(ModBlocks.ICE_ETHER_LEAVES.get()); dropSelf(ModBlocks.ICE_ETHER_PLANKS.get());
|
树叶的我们暂时先这么写着,后面有了树苗我们再修改
语言文件
1 2 3 4 5 6
| add(ModBlocks.ICE_ETHER_LOG.get(), "Ice Ether Log"); add(ModBlocks.ICE_ETHER_WOOD.get(), "Ice Ether Wood"); add(ModBlocks.STRIPPED_ICE_ETHER_LOG.get(), "Stripped Ice Ether Log"); add(ModBlocks.STRIPPED_ICE_ETHER_WOOD.get(), "Stripped Ice Ether Wood"); add(ModBlocks.ICE_ETHER_PLANKS.get(), "Ice Ether Planks"); add(ModBlocks.ICE_ETHER_LEAVES.get(), "Ice Ether Leaves");
|
Tag
方块
1 2 3 4 5 6 7 8 9
| tag(BlockTags.LOGS_THAT_BURN) .add(ModBlocks.ICE_ETHER_LOG.get()) .add(ModBlocks.ICE_ETHER_WOOD.get()) .add(ModBlocks.STRIPPED_ICE_ETHER_LOG.get()) .add(ModBlocks.STRIPPED_ICE_ETHER_WOOD.get()); tag(BlockTags.LEAVES) .add(ModBlocks.ICE_ETHER_LEAVES.get()); tag(BlockTags.PLANKS) .add(ModBlocks.ICE_ETHER_PLANKS.get());
|
物品
1 2 3 4 5 6 7 8 9 10 11 12
| tag(ItemTags.PLANKS) .add(ModBlocks.ICE_ETHER_PLANKS.get().asItem()); tag(ItemTags.LOGS) .add(ModBlocks.ICE_ETHER_LOG.get().asItem()) .add(ModBlocks.STRIPPED_ICE_ETHER_LOG.get().asItem()) .add(ModBlocks.ICE_ETHER_WOOD.get().asItem()) .add(ModBlocks.STRIPPED_ICE_ETHER_WOOD.get().asItem()); tag(ItemTags.LOGS_THAT_BURN) .add(ModBlocks.ICE_ETHER_LOG.get().asItem()) .add(ModBlocks.STRIPPED_ICE_ETHER_LOG.get().asItem()) .add(ModBlocks.ICE_ETHER_WOOD.get().asItem()) .add(ModBlocks.STRIPPED_ICE_ETHER_WOOD.get().asItem());
|
模型文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| logBlock(((RotatedPillarBlock) ModBlocks.ICE_ETHER_LOG.get())); axisBlock(((RotatedPillarBlock) ModBlocks.ICE_ETHER_WOOD.get()), blockTexture(ModBlocks.ICE_ETHER_LOG.get()), blockTexture(ModBlocks.ICE_ETHER_LOG.get())); axisBlock((RotatedPillarBlock) ModBlocks.STRIPPED_ICE_ETHER_LOG.get(), ResourceLocation.fromNamespaceAndPath(TutorialMod.MOD_ID, "block/stripped_ice_ether_log"), ResourceLocation.fromNamespaceAndPath(TutorialMod.MOD_ID, "block/stripped_ice_ether_log_top")); axisBlock((RotatedPillarBlock) ModBlocks.STRIPPED_ICE_ETHER_WOOD.get(), ResourceLocation.fromNamespaceAndPath(TutorialMod.MOD_ID, "block/stripped_ice_ether_log"), ResourceLocation.fromNamespaceAndPath(TutorialMod.MOD_ID, "block/stripped_ice_ether_log"));
blockItem(ModBlocks.ICE_ETHER_LOG); blockItem(ModBlocks.ICE_ETHER_WOOD); blockItem(ModBlocks.STRIPPED_ICE_ETHER_LOG); blockItem(ModBlocks.STRIPPED_ICE_ETHER_WOOD);
simpleBlockWithItem(ModBlocks.ICE_ETHER_PLANKS.get(), cubeAll(ModBlocks.ICE_ETHER_PLANKS.get())); simpleBlockWithItem(ModBlocks.ICE_ETHER_LEAVES.get(), models().cubeAll("ice_ether_leaves", modLoc("block/ice_ether_leaves")).renderType("cutout"));
|
稍微有些复杂,不过也还行
测试
那么跑完数据生成之后,放好材质文件,注意原木的材质文件分为顶(底)面和侧面,有两个
然后就可以去游戏里测试了