我的世界1.20.1模组开发---7.添加物品(进阶版)

发布时间 2023-11-09 09:43:44作者: 小明同学404

介绍

  前面我们已经介绍过了如何添加我们mod的物品,单那些物品都只是一些用于合成的物品。例如我们的各种矿石、建筑方块等,这些物品只能用于合成或者装饰,这次我们就来添加一个具有实际功能的物品,比如一些模组里的魔法杖或者武器之类的。这些物品通过按下指定的按键会有其他的功能,功能我们可以自定义,要实现这种功能,我们需要在我们的item包下创建一个该物品的类,通过继承Item类并重写了里面的方法实现各种各样的功能。下面就来简单介绍一些Item类。

  Item类

  Item类用于表示游戏中的物品,可以用来设置物品的属性、特征等。这个类实现了一系列的接口,这些接口中定义了许多的方法,这些方法可以帮助我们获取一些该物品的信息,或者在指定的事件触发时执行该方法体。我们想触发某事件时执行某个方法时,我们只需要找到父类对应的回调方法并重写即可。下面介绍几个可能用到的方法。

//右键使用物品时触发
    @Override
    public InteractionResultHolder<ItemStack> use(Level pLevel, Player pPlayer, InteractionHand pUsedHand) {
        //主手右键
        if(!pLevel.isClientSide()&&pUsedHand==InteractionHand.MAIN_HAND){
            pPlayer.getCooldowns().addCooldown(this,50);//设置冷却时间
            pPlayer.sendSystemMessage(Component.literal("主手使用"));//向玩家发送一条信息
        }
        //副手右键
        if(!pLevel.isClientSide()&&pUsedHand==InteractionHand.OFF_HAND){
            pPlayer.getCooldowns().addCooldown(this,50);//设置冷却时间
            pPlayer.sendSystemMessage(Component.literal("副手使用"));//向玩家发送一条信息
        }
        return super.use(pLevel, pPlayer, pUsedHand);
    }

  父类中的use方法是当我们手持该物品右键时触发这个方法,从而执行方法体的内容。我们在自己的物品类里只需要重写这个方法,并添加自己的逻辑即可。这里我实现的功能就是当我们主手或副手手持该物品右键时,会向玩家发送一条信息提示我们是在主手使用的还是副手使用的物品。

  在use方法中有一个pLevel参数,我们可以用这个参数判断是在服务端还是客户端,use方法执行是客户端和服务器端都会执行,所以我们右键一次会收到2条消息。所以设置了只在服务器端执行。其实游戏分为客户端和服务器端,一般服务器端用于处理游戏的一些规则和逻辑(玩家之间的互动,交流等),客户端用于处理本地的事件(玩家与环境之间的交互)等。现阶段先不用纠结这些事情,以后会详细介绍一下的(等我搞明白之后x.x)。

    //当物品被玩家丢出时触发
    @Override
    public boolean onDroppedByPlayer(ItemStack item, Player player) {
        player.sendSystemMessage(Component.literal("我被丢弃了"));
        return super.onDroppedByPlayer(item, player);
    }

  onDroppedByPlayer方法是该物品被玩家丢出时触发的,这里我们设置的是玩家丢出该物品后向玩家发送一条“我被丢弃了”的信息。

  通过上面两个例子应该能很好的说明了怎么通过重写父类的方法实现我们自己的功能等等,下面就开始具体上代码。

代码

  我们在item包下再创建一个custom包,用于放我们有特殊功能的物品,在custom包下创建一个EightBalltem类,这个类是我们的有特殊功能的类,该类要继承Item类,之后再根据我们想实现的功能,重写父类对应的方法即可。

 

public class EightBallItem extends Item {
    public EightBallItem(Properties pProperties) {
        super(pProperties);
    }

    //物品右键使用
    @Override
    public InteractionResultHolder<ItemStack> use(Level pLevel, Player pPlayer, InteractionHand pUsedHand) {
        if(!pLevel.isClientSide()&&pUsedHand==InteractionHand.MAIN_HAND){
            ouputRandomNumber(pPlayer);
            pPlayer.getCooldowns().addCooldown(this,50);//设置冷却时间
            pPlayer.sendSystemMessage(Component.literal("主手使用"));
        }

        if(!pLevel.isClientSide()&&pUsedHand==InteractionHand.OFF_HAND){
            ouputRandomNumber(pPlayer);
            pPlayer.getCooldowns().addCooldown(this,50);//设置冷却时间
            pPlayer.sendSystemMessage(Component.literal("副手使用"));
        }
        return super.use(pLevel, pPlayer, pUsedHand);
    }

    //当物品被玩家丢出时触发
    @Override
    public boolean onDroppedByPlayer(ItemStack item, Player player) {
        player.sendSystemMessage(Component.literal("我被丢弃了"));
        return super.onDroppedByPlayer(item, player);
    }

    //鼠标经过物品时显示文字,按下shift键后显示另一行提示文字
    @Override
    public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List<Component> pTooltipComponents, TooltipFlag pIsAdvanced) {
        if(Screen.hasShiftDown()){//按下shift键
            //按下shift键显示的信息,字体设置为白色
            pTooltipComponents.add(Component.literal("right click to get a random number of 0-7").withStyle(ChatFormatting.BLUE));
        }
        else{
            //鼠标经过时的信息,字体设置为绿色
            pTooltipComponents.add(Component.literal("press shift to see more informant").withStyle(ChatFormatting.GREEN));
        }

        super.appendHoverText(pStack, pLevel, pTooltipComponents, pIsAdvanced);
    }
    
    //产生一个随机数发送给玩家
    public void ouputRandomNumber(Player player){
        player.sendSystemMessage(Component.literal("the number is "+Math.floor(Math.random()*8)));
    }
}

  这样我们的有特殊功能的物品类就写好了,之后再将该物品依次添加到物品注册表、、创造模式物品栏、语言文件生成器、贴图即可。

 在ModItems类添加物品到注册表

    //添加功能物品
    public static final RegistryObject<Item>EIGHTBALL=ITEMS.register("eight_ball",
            ()->new EightBallItem(new Item.Properties().stacksTo(1)));//最大堆叠数为1

  在ModCreativeModeTab类添加物品到创造模式物品栏

    public static final RegistryObject<CreativeModeTab>TEST1_TAB=CREATIVE_MODE_TABS.register("test1_tab",
            ()-> CreativeModeTab.builder()
                    .icon(()->new ItemStack(ModItems.YUANSHI.get()))//设置mod物品栏的图标
                    .title(Component.translatable(TEST1_TAB_STRING))//设置mod物品栏的标题
                    //开始向物品栏里添加我们新增的物品
                    .displayItems((pParameters, pOutput) -> {
                        //-----------------------------------
                        pOutput.accept(ModItems.EIGHTBALL.get());//这一行
                        //-----------------------------------
                    })
                    .build());//构建完成

   在ModLangGen类添加物品的语言文件

    @Override
    protected void addTranslations() {
        //物品
        //直接调用add方法,传入物品和物品对应的名字即可
        add(ModItems.EIGHTBALL.get(),"EightBall");

    }

  在对应位置放置贴图

  最后再执行RunData命令生成json文件即可进入游戏。