开启辅助访问     
收藏本站

站内搜索

搜索

Minecraft(我的世界)苦力怕论坛

[闲聊] 自定义箱子来了

 发表于 4 天前 来自手机|显示全部楼层|阅读模式 IP:山西省

还记得我在 2025 年最后一天发的第 125 期闲聊帖吗?它的标题是“自定义箱子的可能”。今天是 2026 年 8 月 19 日,在最新的 1.26.50.26 中,他们终于加入了自定义箱子的功能。

"minecraft:block_entity": {
  "container": {
    "slot_count": 8
  }
}

这就是他们设计的 JSON 模式,其中 slot_count 表示这个自定义容器的容量,是一个整数,取值范围 [1, 54]

他们目前就开放了这一个字段,不过能定义从 1 到 54 的任意数量的槽位。我尝试把它指定为 8,结果看起来是这样的:

Screenshot_2026-08-19-09-31-59-11_5c8300b655012b1930f2e0a7b81bf6a9.jpg

看来它不会自动居中什么的,只是从左到右排列,而且 UI 上没有容器名称。


1.26.50.26 还更新了一大堆 POI(Point of Interest,兴趣点)和世界时钟相关的内容,但是对我的影响不大,我也看不出来怎么把这些内容用到实际生产里。

还有个关于维度的事情,第 162 期里说的维度高度限制只能小于等于主世界的问题在这个版本修复了。我们又能在 1024 格高的世界里造奇观了!

Screenshot_2026-08-19-10-05-13-04_5c8300b655012b1930f2e0a7b81bf6a9.jpg


接着昨天的四个项目,第三个项目是拖拽天体来调整时间的功能。这个纯粹是我的突发奇想。每次看着天上的太阳,我都会想,要是能直接拖拽它,那不就可以玩弄时间了吗?

这个项目非常简单,而且我认为是最简单的一个,它的核心在于将玩家视线映射到一天的时间上。

这时候我遇到了一个难题。太阳和月亮到底是怎么运动的?它们会在天空中做匀速圆周运动吗?我查了一下 Wiki,用“天空”“太阳”这样的关键词找到了两个页面,但是没有看到期望的天体运行旋转角度表。不过我确实查到了太阳位于各顶点时对应的一天中的时刻。

后来我决定莽一把,直接假设它们做匀速圆周运动,这样可以很方便地把视线单位向量映射到时刻。数学方面,自然还是 AI 出手。尽管如此,这次我碰到了一个非要说太阳围绕 Y 轴转的 AI,我花了好大力气,才让它记住太阳是东升西落的,是在 XY 平面上转的。

我依旧让 AI 参考之前的两个项目,然后开始了混乱无比的叙述:

现在我希望让太阳 / 月亮跟随玩家的视线移动而移动,即根据玩家旋转角度的 pitch 值修改时间。太阳东升西落,所以只有玩家的旋转角度的 yaw 值在 90 度或者 270 度(-90 度)左右(误差允许 15 度),才能操控太阳。
world 对象上有一些方法,可以操作时间。
getAbsoluteTime() 返回自游戏开始以来流逝的时间,即 day * 24000 + daytime,其中 day 为天数,daytime 为这一天的时间
setAbsoluteTime() 设置绝对时间,与 getAbsoluteTime 返回的值类似
getTimeOfDay() 返回 daytime
setTimeOfDay() 设置 daytime
Minecraft 的一天有 24000 ticks,daytime 取值范围也是 [0, 24000]
在 6000 ticks 时,太阳位于最高处。在 11834 ticks 时,月亮出现在地平线上,此时太阳在它的对面。
18000 ticks 时,月亮位于最高处。
22300 ticks 时,太阳出现在地平线上。
玩家的 pitch 取值范围 [-90, 90],其中 -90 表示抬头,90 表示低头。

玩家开始操控天体时,如果 yaw 满足条件(视线足够接近东升西落的天体轨道),那么寻找最近的天体,这就是即将操控的天体。首先计算玩家的视线与天体轨道的交点,根据角度与时间的映射关系,找到玩家此时指定的时间。这个时间与当前时间对比,如果在太阳的范围内则操控太阳,否则操控月亮。之后根据附件中的插值动画,把当天的时间设为一个计算出的值,让天体看起来像是固定在玩家视线所指的方向一样。玩家绕着轨道拖动天体时,不仅要处理一天中的时间,还要处理跨天的情况。

先不要写代码,把上面的思路整理清楚,如果有不明确的地方提出来

然后就是猛猛地测试……

虽然起初我又遇到了一堆奇怪问题,比如只要看太阳它就会随机乱动,比如完全抬头和斜着仰望天空的行为不一致,但是最后我还是做好了这个功能。最初我想让玩家控制他们看向的比较近的天体,但是后来我发现是这个功能破坏了代码,现在玩家控制的天体就比较固定。

我还想给这个功能加一点音效。我脑海中有一种音效:在一分钟内拨动开关,首先在 30 秒内把它拨动 10 次,然后在 15 秒内再拨动 10 次,然后是 7.5 秒,然后是 3.75 秒……开关的响声会越来越快,频率越来越高,最后听起来就像发动机轰鸣一样。同理,如果快速拖拽太阳,应该能听到钟表里齿轮快速转动的声音。说干就干,我修改了代码,根据位移量决定音调,但是听起来不理想;套一个指数模型上去,依旧不理想。只好扔掉这个功能。但是写好的代码不能浪费,于是我加了个参数,用来决定是否播放音效,默认为 false

后来我在随意玩弄音效的时候,突然发现有个音符盒的音色非常合适,虽然不是机械转动的声音,但是听起来非常空灵,很适合这个主题。于是就成了这个视频里的样子。


最后一个项目是个老想法了,它的代码量可以和其他三个项目加起来的量相提并论。

现在很多附加包有传送功能,大体上就是在世界里标记一些地点,然后就可以随地大小传。最简单的实现方式,当然是用他们提供的 UI 接口了。还有一些附加包,为了生存模式友好,把传送功能做成了某种仪式,然而到了选择目的地的时候,还是要打开一个表单。

我想做点真正好玩的东西。我几乎没看过网文,但是还是第一时间想到了三维模型。如果我们把所有路径点做成一张微缩的三维地图,这样看起来就有趣多了,而且选择目的地也变成了一种更直观的操作。

这次不能参考之前的三个项目了,因为这次的项目过于独特,而且复杂度比较高。项目实现的第一步,从描述最初的球体空间开始,这时候问题还不涉及 Minecraft。我想,如果我们在保留位置关系的情况下,把所有路径点都压缩到一个球里,那么既容易选择目的地,又可以形成肌肉记忆。

现在,在三维空间中有一些点,假设有部分点是比较密集的,还有几个离原点非常远的点,有没有什么办法,能把它们变换到以原点为中心,半径 r 的球内部,同时还在一定程度上保留点与点之间的位置关系,每个点之间的距离也一定要大于 a?直接缩放肯定不行,比较密集的点会太密集。加入参数 a,就是为了防止点太近。比如原先的点在 x z 轴上可能都是几千甚至几万的,要显示在 r = 16 的球内部。我在设计一个传送点的项目,这些点都会是玩家指定的他们可以传送去的地方。

我的眼前很快出现了我看不懂的高级方案。还好我不需要理解那些数学,而这种复杂度的数学尚且可以由 AI 搞定。

接下来,非常重要的一点是设计数据结构,因为传送点是要持久化存储的,即使退出重进也应该保留。于是我开始描述整个项目的大致形态,也让它帮我随便设计一个数据结构。

在我的设想中,这个全息传送地图应该可以绘制每个点(使用球体的线框),还能记录玩家在点与点之间的穿梭路径。在添加点的时候,一个子区块(16 * 16 * 16)的空间中只能添加一个点,距离太近就用不着传送了。玩家添加了点之后,就可以对准它,打开全息传送地图,然后对准要传送的点,开始传送了。这样,我们就可以在两个点之间记录一条路径。玩家也可以在没有传送点的地方,使用某个物品来直接打开全息传送地图,这时候由于不知道起始点,不会记录路径。随着玩家使用地图传送的次数增多,路径网络也会逐渐建立起来。对于每个点,为了让玩家记住它们,它支持颜色标记和名称标记。为了实现路径记录的功能,也许可以给每个点分配一个唯一 id。现在来设计一个数据结构。

它设计的结构没有让我满足,它把路径分开存储了,但是我想把路径数据放在每个节点里。

我认为路径点的数据结构中,id 可以是一个自增整数,比较简单,省空间;subChunkKey 是不必要的,我们可以通过 location 计算出它所在的子区块位置。然后我们不需要独立存储路径,而是把它存储在路径点下方,在 lastUsedAt 旁边,我们新增一个 path 对象,其中的键是这条路径的目的地 id,值是一个包含 countlastUsedAt 的对象。这样也能方便地记录传送方向。另外,路径点的颜色应该是 {red, green, blue, alpha} 格式的,其中每个分量取值 0-1DebugLine 绘制路径的时候,我们分多段绘制,线的颜色是两个节点的颜色渐变,不透明度则表示这个路线的使用次数。

在设想中,路径点之间的路径是渐变色的线条。但是考虑到路径点很容易变多,这时候再给那么多线条绘制渐变色就比较卡了,我就放走了这个功能。而且我最初的想法是根据一条路径的使用次数,绘制不同数量的相同路径,后来为了减少卡顿,也改成了修改线条不透明度。

最后我让它总结方案,根据方案写代码,整个系统的框架就突然无中生有冒出来了。这时候我犯了一个错误,没有想清楚如何确定一次传送的起始点,后来我又专门修了一下才做好。

之后我又临时起意,给整个系统加了个球体线框,还有打开动画,又注入了一堆灵魂音效,这就算是做好了。

我还专门做了一个粒子,玩家选中一个传送节点的时候,它就会爆开一些粒子。不知道这想法怎么来的。还有一点,玩家选中节点开始传送的时候,那个动画可不仅仅是为了美观。事实上,玩家确认传送的一瞬间,我就在目的地创建了一个常加载区块,只有它加载完成,才会进入最终的传送动画。相机会一头扎进节点里,然后电光火石之间,随着升调的传送门音效,玩家一瞬间出现在目的地,丝毫没有陷入未加载区块的卡顿与茫然。因为传送动画必须在目的地加载完成后触发,即使是性能不好的手机,看起来也在传送后瞬间完成了目的地的加载,就很爽。如果不看代码,一个普通玩家又怎么会想到,目的地是在传送之前加载好的呢……

卡顿危机,当然是有的。为了测试传送点的功能,我加入了一个选项,会自动把所有生物群系都作为路径点添加到全息投影地图里,这时候打开地图就有点卡。但是后来我发现,这不是因为算法效率低下,我只是把每个路径点的绘制复杂度调得太高了。调低一些后,它仍然那么流畅。

而且最神奇的是,因为预加载了区块,用它跨维度传送,和在一个维度里传送的卡顿差不多。这就像是传送到了一个维度里的不同地点一样!


开发完这四个项目,我又没有热情了,想不到什么好点子。而且不知道是不是即将升入高三的原因,我听说这次开学的日期提早了一天,本来是 9 月 1 日,这次变成了 8 月 31 日。

下面这句话,就很神奇。

假期结束,我也要结束了……

最近我特别想读一读自己之前写的文章,很难想象我是怎么从四年级下学期就开始在纸上写《学校琐事》,不停地写,还一直保留到现在的。最近(其实不是很近了,但是相对最近)我还数字化了这些文章,可以随时查阅。我还想看看自己在开学前都写了些什么,把它们找出来读一读,一定很有趣。

苦力怕论坛,感谢有您~
 发表于 4 天前|显示全部楼层 IP:广东省
好可怕的技术力
2#4 天前回复收起回复
苦力怕论坛,感谢有您~
回复支持

使用道具举报

本版积分规则

本站
关于我们
联系我们
坛史纲要
官方
哔哩哔哩
技术博客
下载
网易版
安卓版
JAVA
反馈
意见建议
教程中心
更多
捐助本站
QQ群
QQ群

QQ群

访问手机版

访问手机版

手机版|小黑屋|系统状态|klpbbs.com

木韩网络 提供支持 | GMT+8, 2026-8-23 08:54

声明:本站与Mojang以及微软公司没有从属关系

Powered by Discuz! X3.4