我的世界1.20.1模组开发---8.添加方块(进阶版)

发布时间 2023-11-20 21:33:56作者: 小明同学404

介绍

  最近事情比较多,没什么时间写博客了都,这次忙里偷闲,又通过看源码学会了一些新的东西,趁着记忆尤甚,感觉记下来。这次是添加具有一些功能的方块,和上一篇添加有特殊功能的物品差不多,当我们放置方块、破坏方块、站到方块上等都能添加指定的功能。写法和上次也类似,我们只需要新建一个该方块的类,并继承Block类,实现或重写一些必要的方法之后,再通过重写一些父类特有的方法,当在游戏里触发某个特殊的事件时调用这个方法,以此来实现我们某种特殊功能。下面就介绍几个父类里我们可能会重写的几个方法。

  同样也有use方法,当我们对方块进行右键或者其他能触发该方法的事件发生时,就会调用下面的逻辑。

    //当我们对方块点击时触发该方法,客户端和服务器端都会执行,我们一般会只在一边执行
    @Override
    public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) {
        //如果在客户端且用主手点击了方块触发
        if(pLevel.isClientSide()&&pHand==InteractionHand.MAIN_HAND){
            pPlayer.sendSystemMessage(Component.literal("use被触发了"));
        }
        return super.use(pState, pLevel, pPos, pPlayer, pHand, pHit);
    }

   stepOn方法当实体踩到方块上时就会触发,我们可以获取到这个实体的实例对象,并对这个实体进行一些生命或者其他的修改。

    //当有实体站到方块时触发(怪物、动物、村民都可以)
    @Override
    public void stepOn(Level pLevel, BlockPos pPos, BlockState pState, Entity pEntity) {
        //如果实体是活着的实体就给这个实体添加一个跳跃提升buff
        if(pEntity instanceof LivingEntity livingEntity){
            livingEntity.addEffect(new MobEffectInstance(MobEffects.JUMP,200,2));
            livingEntity.sendSystemMessage(Component.literal("站上了这个方块"));
        }
        super.stepOn(pLevel, pPos, pState, pEntity);
    }

  setPlaceBy方法当该方块被实体放置时调用,同样可以获取实体对象,对其属性进行修改。

   //被放置时调用
    @Override
    public void setPlacedBy(Level pLevel, BlockPos pPos, BlockState pState, @Nullable LivingEntity pPlacer, ItemStack pStack) {
        if(pLevel.isClientSide()){
            pPlacer.sendSystemMessage(Component.literal("放置了这个方块"));
        }
        super.setPlacedBy(pLevel, pPos, pState, pPlacer, pStack);
    }

  下面介绍完常用的父类的方法,就直接给出示例代码了。

代码

  我们在block包下新建一个custom包,用来存放我们自定义的具有特殊功能的方块类,在custom包下新建JumpBlock类,这个类继承Block类,并重写父类的方法。

public class JumpBlock extends Block {

    public JumpBlock(Properties pProperties) {
        super(pProperties);
    }

    @Override
    public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) {
        if(pLevel.isClientSide()&&pHand==InteractionHand.MAIN_HAND){
            pPlayer.sendSystemMessage(Component.literal("use被触发了"));
        }
        return super.use(pState, pLevel, pPos, pPlayer, pHand, pHit);
    }

    @Override
    public void stepOn(Level pLevel, BlockPos pPos, BlockState pState, Entity pEntity) {
        if(pEntity instanceof LivingEntity livingEntity){
            livingEntity.addEffect(new MobEffectInstance(MobEffects.JUMP,200,2));
            livingEntity.sendSystemMessage(Component.literal("站上了这个方块"));
        }
        super.stepOn(pLevel, pPos, pState, pEntity);
    }

    @Override
    public void setPlacedBy(Level pLevel, BlockPos pPos, BlockState pState, @Nullable LivingEntity pPlacer, ItemStack pStack) {
        if(pLevel.isClientSide()){
            pPlacer.sendSystemMessage(Component.literal("放置了这个方块"));
        }
        super.setPlacedBy(pLevel, pPos, pState, pPlacer, pStack);
    }

    @Override
    public void playerDestroy(Level pLevel, Player pPlayer, BlockPos pPos, BlockState pState, @Nullable BlockEntity pBlockEntity, ItemStack pTool) {
        pPlayer.sendSystemMessage(Component.literal("破坏了这个方块"));
        super.playerDestroy(pLevel, pPlayer, pPos, pState, pBlockEntity, pTool);
    }
    
}

  完成上述工作后,还需要以此把该方块加到方块注册表、创造模式物品栏、方块模型文件生成器、语言文件生成器,并添加对应的贴图。

  到ModBlocks类里注册方块。

    public static final RegistryObject<Block>JUMP_BLOCK=registryBlock("jump_block",
            ()->new JumpBlock(BlockBehaviour//注意,这俩要new一个JumpBlock,和之前的有所不同
                    .Properties.of()//设置方块的一些属性
                    .strength(1.5F, 6.0F)
            ));

  到ModCreativeModeTab类里添加方块到创造模式物品栏。

pOutput.accept(ModBlocks.JUMP_BLOCK.get());

   到ModBlockModelGen类设置该方块的模型。

this.registerBlockModelAndItem(ModBlocks.JUMP_BLOCK.get());

  到ModLangGen类添加语言文件

add(ModBlocks.JUMP_BLOCK.get(),"Jump_Block");

  到指定目录下添加方块的贴图文件

  之后RunData成果后直接RunClient启动游戏即可。