欢迎光临散文网 会员登陆 & 注册

方块,以及方块状态

2022-10-23 00:17 作者:道家深湖  | 我要投稿

在世界里放置普通方块,方式如下。

world一般是你所调用的接口里包含的。比如,如果想做一个物品“点石成金”,他在背包里时刻都把脚底下变成金块:

这肯定有问题。问题在哪呢?脚底下是空气的时候也变金块,走在空中的话,下不去了,因为即使挖掉刚生成的金块,也会再刷一个金块出来。

一种想法是,我们让这个能力变为可控的,比如只有拿在主手的时候才生效;另一种想法是,我们不把空气变成金块,只改变既有的石头方块。怎么判断世界里某个位置是什么呢?

一个set,一个get,很直白,是不是?

那么,怎么判断脚下是不是石头呢?一时间我会想到很多种方式,并且他们不等价:

第一种,判断方块是不是石头这个Block;第二种,判断方块状态是不是石头的默认状态。

乍一看两者等价,但实际上差的很远。

变种

安山岩、闪长岩、花岗岩,这污染背包三兄弟,以及它们的磨制版本,与石头的注册名相同,这就说明它们是同一方块的不同状态。如果你使用第二种,那么算上石头本身,这七个兄弟都会受到影响。

第三种就更是走远了。

骨头方块的代码

凡是质地是石头的方块都会被算进去,这包括……发射器,附魔台,骨头方块什么的。具体哪些算石头,在游戏里很难看到,只能靠翻源码,查询Material.ROCK的引用。注意是ROCK,不是STONE。方块质地没有STONE。

好,我们现在知道如果只作用于“石头”,那么应该判断state==defaultState,那么,如果我想判断花岗岩这种不是默认状态的,又要怎么办呢?我们看一段BlockStone的代码。

石头类里定义了一个VARIANT对象,它暗示石头会有这么个属性,用来产生变种。注意,这里写了不一定就有,这里没写不一定就没有。关键在于Block里是否重写createBlockState:

石头的长这样,所以说明它只有一个属性,那就是“VARIANT”。这个VARIANT不一定写在石头里,也可以写在别的地方。

我自己写一个方块,也可以用石头的这个VARIANT属性,所以看一个东西有什么属性一定不要看类开头声明了什么成员,一定要看这里。

相应地,如果我只写了个MY_VARIANT对象在那,但是我忘了写进createBlockState,那那个对象就报废了,方块还是没变体。当然,要正确定义一种全新的有变体的方块,还要再写好几个地方,每个都容易犯错,篇幅所限,留到其他专栏里,这里先不展开。

这个是BlockNewLeaf的代码:

你可以看到,这种叶子具有三套子状态,可以排列组合。注意,这个VARIANT是BlockNewLeaf.VARIANT,和石头里的不是同一个,只是同名罢了。毕竟叶子是没有磨制花岗岩这种选项的。

我们再看看红石线(BlockRedStoneWire):

他有五套子状态在这排列组合。

那么,怎么指定子状态,答案已经出来了,就是BlockStone构造函数里那样。

给我们的IBlockState调用成员withProperty,返回新的IBlockState。第一个参数是VARIANT这样的PropertyEnum对象,第二个是对象的值。通俗来说就是,state.withProperty(类型,花岗岩),这样。

对于树叶那种有多个状态的,只能多调用几次,分别指定:

state.withProperty(类型,橡树).withProperty(检查腐烂,不)

不指定的就会按照默认,或者state之前的状态来。

所以,我们想判断是不是磨制花岗岩,可以:

但这还有个问题。有多套子状态时,我只想判断其中一套的话,难道要把其他的几个值都排列组合吗?显然不是。我们可以直接获取某个state子状态的值。你猜这个获取选项值的接口叫啥?getProperty?不好意思答错了,他叫getValue。不对称,是不是很想打人?


总结:

World::setBlockState

World::getBlockState

IBlockState::withProperty

IBlockState::getValue

方块,以及方块状态的评论 (共 条)

分享到微博请遵守国家法律