【Minecraft】Fabric Mod开发完整流程4 - 自定义物品方块以及食物、燃料

目录

    • 自定义物品与方块
      • 自动侦测矿藏工具
        • 工具功能
        • 实现
        • 执行结果
      • 自定义音乐方块
      • 自定义食物
      • 自定义燃料

自定义物品与方块


自动侦测矿藏工具

探测器纹理下载地址: https://url.kaupenjoe.net/mbkj57/assets

众所周知,正经人永远不喜欢常规套路挖矿,如果能有一个自定探测脚下矿藏的工具就好了~
接下来我们将会一步步实现该工具


工具功能

耐久 64,右击方块使用,每次使用无论找到矿藏与否均销毁一点耐久

被右击的方块向下勘察 128 个方块,如果存在铁或者钻石矿石,就会在聊天框反馈给玩家
反之,如果找不到,就输出失败信息


实现

首先创建一个单独的 custom 文件夹,存储我们自定义的物品

新建类 MetalDetectorItem.java 具体位置可以查看下图

在这里插入图片描述


主要代码如下,相信你一定可以看得懂的!

tips:使用 alt+insert 快捷键可以快速添加构造函数哦

package com.example.item.custom;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;

import java.util.Objects;

// extends继承父类Item
public class MetalDetectorItem extends Item {

    // 别忘了构造函数
    public MetalDetectorItem(Settings settings){
        super(settings);
    }

    // 当物品对方块使用的时候(即右键点击方块)
    @Override
    public ActionResult useOnBlock(ItemUsageContext context) {
        // 如果是客户端
        if(!context.getWorld().isClient()){
            // 获取方块位置以及玩家位置,并初始化foundBlock变量以确定是否找到方块
            BlockPos posClicked = context.getBlockPos();
            PlayerEntity player = context.getPlayer();
            boolean foundBlock = false;

            // 据方块坐标,以Y轴为基准向下勘察128格
            // posClicked.down(i)表示当前坐标向下i格
            for(int i=0;i<=posClicked.getY()+128;i++){
                // 逐个获取对应方块状态
                BlockState state = context.getWorld().getBlockState(posClicked.down(i));
                // 判断方块状态如果符合条件,输出成功信息
                if(isTargetBlock(state)){
                    assert player != null;
                    outputTargetBlockCoordinates(
                            posClicked.down(i),
                            player,
                            state.getBlock()
                    );
                    foundBlock=true;
                    break;
                }
            }

            // 如果啥都找不到,输出失败信息
            if(!foundBlock){
                assert player != null;
                player.sendMessage(
                        Text.literal("No Target Ore Found!!!")
                );
            }

            // 最后别忘了给玩家手上拿着的物品(也就是我探测器)加上1损耗
            context.getStack().damage(1, Objects.requireNonNull(context.getPlayer()), player1 -> {
                player1.sendToolBreakStatus(player1.getActiveHand());
            });
        }
        return ActionResult.SUCCESS;
    }

    // 探测指定方块是不是铁矿石或者钻石矿石的函数
    private boolean isTargetBlock(BlockState state){
        return state.isOf(Blocks.IRON_ORE) || state.isOf(Blocks.DIAMOND_ORE);
    }

    // 输出矿藏坐标的函数
    private void outputTargetBlockCoordinates(BlockPos blockPos, PlayerEntity player, Block block){
        player.sendMessage(
                Text.literal("Target Ore:"+block.asItem().getName().getString()+" at ("+blockPos.getX()+","+blockPos.getY()+","+blockPos.getZ()+")"),
                false
        );
    }
}


执行结果

在这里插入图片描述


自定义音乐方块

和自定义物品一样,我们新建一个 custom 文件夹存储自定义的方块

按照下图所示位置创建自定义音乐盒方块 SoundBlock.java
在这里插入图片描述


音乐盒的代码很简单,就是右键点击一次就发出一个声音

代码清单 SoundBlock.java

package com.example.block.custom;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

public class SoundBlock extends Block {
    public SoundBlock(Settings settings) {
        super(settings);
    }

    // onUse即为右键点击
    @Override
    public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
        // 在玩家所在位置播放一个声音
        world.playSound(player,pos, SoundEvents.BLOCK_NOTE_BLOCK_BASS.value(), SoundCategory.BLOCKS,1f,1f);
        return ActionResult.SUCCESS;
    }
}

注意,我们在 ModBlocks 里面注册这个方块的时候,不要人为指定 sounds,否则会导致声音播放失败!

这是注册方块的写法

public static final Block SOUND_BLOCK = regBlock("sound_block",
            new SoundBlock(FabricBlockSettings.copyOf(Blocks.WHITE_WOOL)));

自定义食物

番茄纹理下载:https://url.kaupenjoe.net/mbkj61/assets

我们将制作一个番茄,它吃下去会有一定效果


新建类 AwfulTomatoFood.java 用于表示我们的食物

代码清单

package com.example.item.food;

import net.minecraft.command.argument.NbtCompoundArgumentType;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.FoodComponents;
import net.minecraft.nbt.NbtCompound;

public class AwfulTomatoFood {
    // 定义一个食物,使用FoodComponent.Builder
    public static final FoodComponent AWFUL_TOMATO = new FoodComponent.Builder()
            // 补充的饥饿值
            .hunger(2)
            // 设置饱和度(即饥饿值开始掉之前先消耗饱和度)
            .saturationModifier(0.25f)

            // 添加吃后的药水效果
            // 参数一:药水效果,参数二:获得效果的几率
            .statusEffect(new StatusEffectInstance(StatusEffects.POISON,200),0.5f)
            .statusEffect(new StatusEffectInstance(StatusEffects.INSTANT_DAMAGE,1),0.25f)

            // 饥饿值满的时候也可以吃
            .alwaysEdible()
            // 可以喂狗吃
            .meat()
            // 指定该食物是一个零食,此时你吃起来就会非常快(大概是吃普通食物耗费时间的一半)
            .snack()
            .build();
}

注册时不要再像之前注册自定义物品一样直接用这个类!请按照如下代码进行注册

代码清单 ModItems.java

// 要明确告诉编译器你需要注册一个食物,用到FabricItemSettings().food()
public static final Item AWFUL_TOMATO_FOOD = regItem("awful_tomato",
        new Item(new FabricItemSettings().food(AwfulTomatoFood.AWFUL_TOMATO)));

自定义燃料

定义燃料很简单,直接像根据定义普通物品一样定义即可

代码清单 ModItems.java

package com.example.item;

import com.example.TutorialMod;
import com.example.item.custom.MetalDetectorItem;
import com.example.item.food.AwfulTomatoFood;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroupEntries;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.fabricmc.fabric.api.registry.FuelRegistry;
import net.minecraft.item.Item;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;


public class ModItems {

    ...

    // 定义燃料物品
    public static final Item COAL_BRIQUETTE = regItem("coal_briquette",
            new Item(new FabricItemSettings()));

    private static Item regItem(String name,Item item){
        return Registry.register(Registries.ITEM,new Identifier(TutorialMod.MOD_ID,name),item);
    }

    public static void registerModItems(){
        TutorialMod.LOGGER.debug("TutorialMod正在注册Items,MOD_ID:"+TutorialMod.MOD_ID);

        // 在这里使用FuelRegistry注册燃料
        // 参数一:欲注册的燃料名称
        // 参数二:燃料热值(200即为在普通熔炉下熔炼一个物品的时长,这个时间在应用到高炉内是按比例的)
        FuelRegistry.INSTANCE.add(ModItems.COAL_BRIQUETTE,200);
    }
}

这里有一个关键概念要搞清楚

FuelRegistry.INSTANCE.add 接收的第二个参数应该理解为燃料热值,即 200 为一个标准值,能熔炼一个物品;
同理,在高炉中,由于热值固定,所以依然只够熔炼一个物品;
不应该将其理解为燃烧时长,否则移动到高炉里面就是两倍的熔炼时长了,这显然不对!!!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/71457.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

web-xss-dvwa

目录 xss&#xff08;reflected&#xff09; low medium high xss(store) low medium high xss(dom) low medium high xss&#xff08;reflected&#xff09; low 没有什么过滤&#xff0c;直接用最普通的标签就可以了 http://127.0.0.1/DVWA-master/vulnerabili…

AT89C51单片机实现单片机串口互动(中断方式,单片机--单片机,应答)

说一下功能&#xff1a;客户机发送0x01到服务机 2服务单片机应答0xf2到客户机 3客户机接收到0xf2,发送信息153432这6个数字到服务机 4client发送完信息后发送0xaa结束通信 5server接收到0xaa后回复0xaa结束通信&#xff0c;从此老死不相往来 看代码&#xff1a; //发送端…

python ffmpeg合并ts文件

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;点击跳转 当你从网站下载了一集动漫&#xff0c;然后发现是一堆ts文件&#xff0c;虽然可以打开&#xff0c;但是某个都是10秒左右&#xff0c;…

Learning Deep Features for Discriminative Localization

Some Words: 这里主要是我阅读paper的笔记 这篇文章主要是2016年CVPR的一篇文章&#xff0c;中文名是 学习用于判别性定位的深度特征&#xff0c; &#xff08;一&#xff09;Abstract: 在这篇工作中&#xff0c;我们又重新探讨了全局平均池化层&#xff0c;并且阐释了CNN网络…

【uni-app】 .sync修饰符与$emit(update:xxx)实现数据双向绑定

最近在看uni-app文档&#xff0c;看到.sync修饰符的时候&#xff0c;觉得很有必要记录一下 其实uni-app是一个基于Vue.js和微信小程序开发框架的跨平台开发工具 所以经常会听到这样的说法&#xff0c;只要你会vue&#xff0c;uni-app就不难上手 在看文档的过程中&#xff0c;发…

常见分布式ID解决方案总结:数据库、算法、开源组件

常见分布式ID解决方案总结 分布式ID分布式ID方案之数据库数据库主键自增数据库号段模式Redis自增MongoDB 分布式ID方案之算法UUIDSnowflake(雪花算法) 雪花算法的使用IdWorker工具类配置分布式ID生成器 分布式ID方案之开源组件uid- generator(百度)Tinyid&#xff08;滴滴&…

x11 gtk qt gnome kde 之间的区别和联系

Linux 下的图形库介绍 一、Linux 图形领域的基础设施 1.1 X Window X Window从逻辑上分为三层&#xff1a;X Server、X Client和X协议。 最底层的X Server&#xff08;X服务器&#xff09;主要处理输入/输出信息并维护相关资源&#xff0c;它接受来自键盘、鼠标的操作并将…

378. 有序矩阵中第 K 小的元素

378. 有序矩阵中第 K 小的元素 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;__378有序矩阵中第K小的元素__直接排序__378有序矩阵中第K小的元素__归并排序__378有序矩阵中第K小的元素__二分查找 原题链接&#xff1a; 378. 有序矩阵中…

全志T113-S3 Tina-linux --1. 开发环境搭建

1. 硬件环境 1.1 开发板 型号&#xff1a;100ASK_T113-PRO Base V1.1&#xff08;韦东山&#xff09;配置&#xff1a;CPU&#xff1a;T113-S3&#xff0c;RAM&#xff1a;128MB&#xff0c;ROM&#xff1a;128MB T113-S3配置 1.2 上手使用 1.2.1 串口shell 串口shell配置…

面试热题(二叉树的锯齿形层次遍历)

给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3…

Yolov5缺陷检测/目标检测 Jetson nx部署Triton server

使用AI目标检测进行缺陷检测时&#xff0c;部署到Jetson上即小巧算力还高&#xff0c;将训练好的模型转为tensorRT再部署到Jetson 上供http或GRPC调用。1 Jetson nx 刷机 找个ubuntu 系统NVIDIA官网下载安装Jetson 的sdkmanager一步步刷机即可。 本文刷的是JetPack 5.1, 其中包…

zookeeper+kafka

目录 Kafka概述 一、为什么需要消息队列&#xff08;MQ&#xff09; 二、使用消息队列的好处 三、消息队列的两种模式 四、Kafka 定义 五、Kafka 简介 六、Kafka 的特性 七、Kafka 系统架构 分区的原因 八、部署kafka 集群 1.下载安装包 2.安装 Kafka 3.修改…

卷积神经网络实现彩色图像分类 - P2

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;365天深度学习训练营-第P2周&#xff1a;彩色识别&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff1a;K同学的学习圈子…

【考研复习】24王道数据结构课后习题代码|第3章栈与队列

文章目录 3.1 栈3.2 队列3.3 栈和队列的应用 3.1 栈 int symmetry(linklist L,int n){char s[n/2];lnode *pL->next;int i;for(i0;i<n/2;i){s[i]p->data;pp->next;}i--;if(n%21) pp->next;while(p&&s[i]p->data){i--;pp->next;}if(i-1) return 1;…

Vue实现图片懒加载

图片懒加载&#xff08;Lazy Loading&#xff09;是一种前端优化技术&#xff0c;旨在改善网页加载性能和用户体验。它的基本原理是&#xff0c;将网页中的图片延迟加载&#xff0c;只有当用户滚动到图片所在的位置时&#xff0c;才会加载图片内容&#xff0c;从而减少初始页面…

QT生成Word PDF文档

需求&#xff1a;将软件处理的结果保存为一个报告文档&#xff0c;文档中包含表格、图片、文字&#xff0c;格式为word的.doc和.pdf。生成word是为了便于用户编辑。 开发环境&#xff1a;qt4.8.4vs2010 在qt的官网上对于pdf的操作介绍如下&#xff1a;http://qt-project.org/…

易服客工作室:Elementor AI简介 – 彻底改变您创建网站的方式

Elementor 作为领先的 WordPress 网站构建器&#xff0c;是第一个添加本机 AI 集成的。Elementor AI 的第一阶段将使您能够生成和改进文本和自定义代码&#xff08;HTML、自定义代码和自定义 CSS&#xff09;。我们还已经在进行以下阶段的工作&#xff0c;其中将包括基于人工智…

2023年游戏买量能怎么玩?

疫情过后&#xff0c;一地鸡毛。游戏行业的日子也不好过。来看看移动游戏收入&#xff1a;2022年&#xff0c;移动游戏收入达到920亿美元&#xff0c;同比下降6.4%。这告诉我们&#xff0c;2022年对移动游戏市场来说是一个小挫折。 但不管是下挫还是上升&#xff0c;移动游戏市…

pytest fixture 用于teardown工作

fixture通过scope参数控制setup级别&#xff0c;setup作为用例之前前的操作&#xff0c;用例执行完之后那肯定也有teardown操作。这里用到fixture的teardown操作并不是独立的函数&#xff0c;用yield关键字呼唤teardown操作。 举个例子&#xff1a; 输出&#xff1a; 说明&…

剑指 Offer 61. 扑克牌中的顺子

题目描述 从若干副扑克牌中随机抽 5 张牌&#xff0c;判断是不是一个顺子&#xff0c;即这5张牌是不是连续的。2&#xff5e;10为数字本身&#xff0c;A为1&#xff0c;J为11&#xff0c;Q为12&#xff0c;K为13&#xff0c;而大、小王为 0 &#xff0c;可以看成任意数字。A 不…
最新文章