MC Fabric 1.20.1 学习笔记 —— 制作一个独立配方的工作台 01

44 阅读2分钟

目标: 制作一个拥有独立配方的工作台

  • 配方:泥土方块 + 高草丛 = 黏液球 该配方仅能在该工作台使用

tips: 令人反感的是fabric制作组时常给一些好用的方法打上弃用标签,而官方文档又不给出替代方案的使用范例(事实上他们的官方文档一直非常滞后)导致你在编码时有种莫名的恶心感,此时建议大家在编写前给类打上注解@SuppressWarnings("deprecation")以关闭弃用检查(眼不见心不烦)。

制作方块

这个方块类需要有两个主要部分,一是方块实体,二是鼠标右键后要打开GUI界面。

@SuppressWarnings("deprecation")
public class WorkBlock extends Block implements BlockEntityProvider {
    // 方块名称
    public static final String NAME = "work_block";
    // 方块唯一标识
    public static final Identifier ID = new Identifier(ModInfo.MOD_ID, NAME);
    // 方块单例实例
    public static final Block INSTANCE = new WorkBlock(FabricBlockSettings.create().hardness(0.5f));
    // 右键后打开的界面的标题
    private static final Text TITLE = Text.translatable("screen.amazing.work_block");
    // 方块实体
    public static WorkBlockEntity blockEntity;


    public WorkBlock(Settings settings) {
        super(settings);
    }

    // 重载右键事件
    public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
        if (world.isClient) {
            // 客户端不响应右键事件
            return ActionResult.SUCCESS;
        } else {
            // 在方块位置创建GUI界面(人被水冲远会导致GUI界面自动关闭
            NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos);
            // 屏幕创建后立即打开屏幕
            player.openHandledScreen(screenHandlerFactory);
            return ActionResult.SUCCESS;
        }
    }

    // 方块实体必须重写的方法
    @Nullable
    @Override
    public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
        blockEntity = new WorkBlockEntity(pos, state);
        return blockEntity;
    }

    // get时使用单例避免创建过多对象,这里即使并发了也无所谓,多出来的会被垃圾回收,只有创建那一瞬间会卡
    private WorkBlockEntity getBlockEntity(BlockPos pos, BlockState state) {
        if(blockEntity == null){
            blockEntity = new WorkBlockEntity(pos, state);
        }
        return blockEntity;
    }
    
    // 这个方法我们自己不会调用,由fabric在state.createScreenHandlerFactory时进行调用
    @Nullable
    @Override
    public NamedScreenHandlerFactory createScreenHandlerFactory(BlockState state, World world, BlockPos pos) {
        // 创建一个屏幕工厂,其工厂方法是new一个我们自己的WorkBlockScreenHandler类,这个后面会有代码
        return new SimpleNamedScreenHandlerFactory((syncId, inventory, player) ->
                new WorkBlockScreenHandler(syncId, player.getInventory(), inventory, ScreenHandlerContext.create(world, pos)), TITLE);
    }

    // 重写方块被破坏时的方法,在方块实体里面会放入一些东西,如果破坏时不掉落,会吞物品
    @Override
    public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
        super.onBreak(world, pos, state, player);
        this.getBlockEntity(pos, state).doBreak(world, pos);
    }
}

可以看到这里我们还需要去创建方块实体的类和屏幕类,而这些类又会牵扯到更多的新类。我们还有方块材质和合成表数据等json文件需要编写。全部编写完成后仅JAVA代码量约在900行左右。
时间关系先写到这里,后续部分将在本专栏继续更新。