当前位置:首页 > CN2资讯 > 正文内容

我的世界java版酿造台UI 我的世界1.7.10酿造台

1天前CN2资讯

老实说我已经忘了这个mod是怎么写出来的了。

所以下面的代码不能运行是非常正常的。

 

上回书说到,我们处理了玩家拿着背包右键时触发的事件,发送了一条打开背包窗口的命令,但是背包窗口还没有写,这回就来解决这个问题。

这次因为嵌套关系太多,所以我按执行顺序反过来说。

那么先不管上次没有打开的那个GUI。

 

MC中的每一个能放进物品的容器,不管是箱子、熔炉还是酿造台,各自都持有一个自己的内容空间(Inventory)实例,在这个内容空间中各自保存自己的内容物。

内容空间的基类是InventoryBasic,实现了IInventory接口,为了方便,咱直接继承InventoryBasic类。

InventoryBasic类已经实现了大部分内容空间需要的功能,可以粗读一下代码,挺好懂的。

于是我们黑猫背包的内容空间类只需要处理内容物的保存和读取。

1 public class InventoryKuroNeko extends InventoryBasic { 2 public static final String TITLE = "黑猫"; 3 public static final int SLOTS_PER_LINE = 9; 4 public static final int LINES = 2; 5 6 private ItemStack itemStack; 7 8 private String id; 9 10 public InventoryKuroNeko(ItemStack itemStack) { 11 super(TITLE, true, LINES * SLOTS_PER_LINE); 12 13 this.itemStack = itemStack; 14 15 if (!itemStack.hasTagCompound()) { 16 itemStack.setTagCompound(new NBTTagCompound()); 17 id = UUID.randomUUID().toString(); 18 } 19 20 readFromNBT(itemStack.getTagCompound()); 21 } 22 23 public NBTTagCompound writeToNBT(NBTTagCompound compound) { 24 NBTTagList items = new NBTTagList(); 25 26 for (int i = 0; i < getSizeInventory(); i++) { 27 ItemStack itemStack = getStackInSlot(i); 28 if (itemStack != null) { 29 NBTTagCompound item = new NBTTagCompound(); 30 item.setInteger("slot", i); 31 itemStack.writeToNBT(item); 32 items.appendTag(item); 33 } 34 } 35 36 compound.setTag("items", items); 37 38 compound.setString("id", id); 39 40 return compound; 41 } 42 43 public void readFromNBT(NBTTagCompound compound) { 44 if (id == null) { 45 id = compound.getString("id"); 46 } 47 if (id == null) { 48 id = UUID.randomUUID().toString(); 49 } 50 51 NBTTagList items = compound.getTagList("items", 10); 52 53 for (int i = 0; i < items.tagCount(); i++) { 54 NBTTagCompound item = items.getCompoundTagAt(i); 55 56 int slot = item.getInteger("slot"); 57 if (slot >= 0 && slot < getSizeInventory()) { 58 ItemStack itemStack = ItemStack.loadItemStackFromNBT(item); 59 setInventorySlotContents(slot, itemStack); 60 } 61 } 62 } 63 64 @Override 65 public void markDirty() { 66 super.markDirty(); 67 writeToNBT(this.itemStack.stackTagCompound); 68 } 69 }

先扔代码

自己写两个方法,名字可以随便起,我这里一个叫writeToNBT,用于保存内容物,一个叫readFromNBT,用于读取内容物。

保存和读取用到的是NBT机制,NBT全称是什么我已经忘了。

先说保存。

首先创建一个NBT的列表NBTTagList,用于保存各个物品和它们的位置。这个类可以简单理解为一个列表。

然后遍历所有内容空间中的格子,只要发现格子中有物品,就把当前的格子位置保存在一个NBTTagCompound中,这个类理解为一个存储单元。

光保存位置不够,调用现成的API把这个物品的信息也加到存储单元中。

最后把这个存储单元添加到列表里。

这样遍历下来,所有物品的信息都保存起来了,最后把这个列表放到参数中传来的存储单元中。

怎么处理参数中的那个存储单元就不是你的事了。

 

最后是writeToNBT这个方法的调用,按照经验,应该会有一个回调方法,由系统在需要保存内容空间的内容的时候自动调用。

确实有。

找得我好苦啊。

重写父类的markDirty方法,先调用一遍父类的实现,然后加上

writeToNBT(this.itemStack.stackTagCompound);

这里的itemStack指的是使用了这个内容空间的物品,也就是黑猫背包。

在构造方法里接收并保存一下就好了。

 

这样系统就会自动把背包中的所有物品保存到这个背包实例中了。

 

但是光保存不行,还得读取。

于是来处理readFromNBT。

首先回到构造方法里。

第一次打开背包的时候肯定是不会有已经保存了的内容物的,this.itemStack.stackTagCompound这个东西也是不存在的,所以判断一下,初始化一个。

if (!itemStack.hasTagCompound()) { itemStack.setTagCompound(new NBTTagCompound()); id = UUID.randomUUID().toString(); }

再给当前内容空间一个id用来识别不同的背包。

不作id的区分的话就变成末影背包了。

 

现在已经不会有空指针的问题了,于是不管三七二十一,读取一下吧。

我这上面用访问器下面直接访问变量效果是一样的,请不要在意。

首先从物品中保存的存储单元中拿到当前内容空间的id。

然后取出在刚才保存了所有物品的列表NBTTagList,这个方法的第二个参数我忘了是干嘛用的了,照抄吧。

接下来就是遍历了,拿出一个存储单元,找出格子的位置,然后用ItemStack类中的方法和存储单元中保存的信息创建一个物品栈并设置到指定的位置上。

就完美地恢复了之前保存的东西。

 

最后说一下三个常量。

TITLE是内容空间的名称,貌似会显示在界面上。

因为为了方便之后会直接拿箱子的界面来用,所以SLOTS_PER_LINE请不要乱动。

LINES就是行数了,我为了平衡给了个2,箱子貌似是4?给65535应该也是可行的。如果你显示器纵向分辨率有那么高的话……

 

写到这里背包的基本功能就已经完成了,后面就要开始蛋疼了。

如刚才所说,我打算直接复用箱子的界面,但是箱子相关的两个类都用了硬编码,所以没办法用继承的方式来创建背包的界面。

用英文说就是用了一个非常蛋疼的workaround。

 

下一篇再说。



    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/21621.html

    分享给朋友:

    “我的世界java版酿造台UI 我的世界1.7.10酿造台” 的相关文章

    甲骨文与云技术的创新研究探索

    甲骨文的概述 我一直对甲骨文充满兴趣,它不仅是中国古代文字的起源之一,也在历史发展中扮演了重要角色。甲骨文的起源可以追溯到公元前14世纪的商朝晚期,当时的一些卜辞记录在龟甲和兽骨上,这成为了我们了解古代社会、文化和宗教信仰的重要窗口。通过这些文字,我感受到那种历史的厚重感,仿佛能够穿越时间与古人对话...

    深入了解俄罗斯时区对生活与经济的影响

    在这个广袤的国家,谈论俄罗斯时区就如同打开了一本极其丰富的地理和文化百科全书。俄罗斯作为世界上面积最大的国家,领土纵深可谓无比广阔,从西欧一直延伸到东亚。这种东西跨度的特性,使得时区的划分显得尤为重要。俄罗斯实际上拥有11个时区,每个时区不仅仅是时间的概念,更承载着各自地区独特的人文、经济和社会习惯...

    如何选择高性能、美西VPS服务商: 比较、评测及优化建议

    美西VPS概述 美西VPS,简单来说,就是那些位于美国西部地区的虚拟专用服务器,像在洛杉矶这样的城市里。这些服务器给用户提供了一种灵活而高效的托管解决方案,特别是对于需要快速访问和低延迟连接的用户群体。美西VPS的设计理念是为用户提供高性能和高可靠性的服务,同时确保在数据传输时的安全性。 美西VPS...

    inet.ws纽约:高性能VPS服务与折扣优惠码解析

    inet.ws是一家新兴的互联网服务提供商,成立于2020年。尽管公司年轻,但它凭借创新的VPS服务迅速在市场上占据了一席之地。最让人称道的是,inet.ws致力于为用户提供稳定和高效的云服务器体验,尤其是在他们的纽约数据中心,这里被认为是其最重要的运营点之一。 在发展的过程中,inet.ws不断完...

    主机类型与高性能配置详解,选择最适合你的主机方案

    主机的定义与分类 什么是主机? 当我们谈论“主机”这个词时,通常指的是计算机系统,特别是在网络环境中提供服务或资源的设备。我个人觉得主机不仅仅是实体的机器,而是指在网络中扮演着重要角色的一种技术资源。它可以执行各种任务,从存储数据到托管网站,再到运行应用程序,主机的功能几乎无所不包。可以想象,主机就...

    VPS优惠活动解析:如何选择最划算的虚拟专用服务器方案

    在当今互联网环境中,VPS(虚拟专用服务器)为企业和个人用户提供了灵活、高效的解决方案。随着云计算的普及,VPS逐渐成为许多用户的首选。不管是建站、开发、还是日常的数据处理,选择一款合适的VPS至关重要。而在不同的VPS服务提供商中,优惠活动往往能让用户以更实惠的价格体验高质量的服务。 什么是VPS...