当前位置: 我的世界 > 游戏攻略 > 正文

我的世界幽灵方块详解 关于幽灵方块的研究分析

小编:3F时间:2016-12-09 15:02回到游戏园首页

  我的世界幽灵方块详解 关于幽灵方块的研究分析。那下面给大家介绍的则是我的世界游戏中的幽灵方块哦~那下面就带啊大家详细的认识一下什么是幽灵方块吧!有想要了解的玩家点我查看吧!

  游戏园我的世界官方群:325049520  256070479 欢迎各路喜爱我的世界的小伙伴们加入讨论!

  玩服务器的小伙伴们可以加入:141931866 群一起联机玩游戏哦!

  如果你是腐竹的话可以给我们投稿你的服务器哦~投稿地址点我进入

  如果你有心仪的作品或者心得分享的话,欢迎来游戏园投稿,大家可以点击>>>投稿<<<进行投稿哦~ 有奖品哦~

  一、什么是幽灵方块

  mc有两个部分,客户端和服务端。客户端和服务端共同完成了游戏的算法。服务端和客户端各有分工:服务端需要计算实体的行为,客户端需要渲染GUI。每个世界都会有一个服务端作为终端,发送Packet(包)来和客户端交流。至于Packet怎么实现,是通过网络(多人游戏)还是通过本地(单人游戏)来交流就不是游戏这个层面需要管的事情了。为了节约IO资源,mc需要尽可能地减少之间的通讯。于是客户端和服务端分别进行运算,只在必须的情况下才会传递信息,进行同步。幽灵方块就是在同一位置上,服务端和客户端不同的方块。为了节约版面,我们把幽灵方块称为 G方块,客户端称为C,服务端称为S 。幽灵方块在客户端和服务端的值分别为G方块的C值和S值。

  二、幽灵方块的产生

  G方块四处存在。在任意一个方块同步的包没有发送到C时,这都是一个G方块。不过有时,方块更新并不会产生一个方块同步。这点是程序员可控的。

  制造幽灵方块会有很多可能的方法,只是许多方法我们并不知道而已。最简单粗暴的如写mod,强制在S设置一个不同步到C的方块,或者直接在C设置一个方块,都可以完成这一点。

  利用活塞是最普遍的方法了。为了节约资源,S的活塞并不同步方块更新,而是同步一个叫做方块事件的东西,让C自己完成推出的计算。在这个计算过程中可能会发生时序等的一些差异,导致幽灵方块的产生。这也是我们将会重点分析的一个部分。

  另外,我猜想通过区块加载的某些方式可以使S认为这个方块更新不需要同步到C。不过还没有实验。

  在研究活塞的行为是如何导致G方块产生的,我们需要先理解游戏的微观时序和活塞的微观行为。

  S端每tick更新的时间轴如下:

  Next Tick Entry(NTE)

  PlayerManager Update(PMU)

  这个是我新加的项目,主要负责区块和同步的管理等,卸载区块就是在这里执行的。S端在这一tick中,每个区块(Chunk)需要进行方块同步的位置都会按照顺序添加在一个数组里,在PMU统一发送Packet给C。

  语文老师:这里的“数组”是这篇文章的一个伏笔!高!实在是高!

  注:不要在意上一句话...老实说我觉得PlayerManager这名字起的不好

  Block Event(BE)

  Entity Update 为了不要和工业mod里的电力单位(Electric Unit)搞混,就不要简称了...(雾)老实说我觉得这个成员在幽灵方块的生成中起不到影响,不过为了方便以后修改,就加上了。

  Tile Entity Update(TEU)在这里,由于我打“Tile Entity”和“Tileentity”都看着不顺眼,于是就玩个简称吧..用于方块存放特殊数据,或者在每个循环执行任务。被活塞推出的方块会变成36号方块,其中存放了一个TE。在每个TEU,应该被推动完成了的36号方块就会变成原方块。

  没错,这5个重要的成员就是我们研究G方块的生成必不可少的元素了。

  接下来是活塞的具体行为。由于不好描述,本文将由伪代码的形式形容。对于36号方块(推动中的方块),清除的意思是把它变成正在推的那个方块。

  checkForMove(当活塞收到更新时调用,只由S执行){

  判断自己是否有信号和自己的状态,如果是有信号的收回态,调用addblockevent。如果是无信号的推出态,先设置自己为收回态(更新,同步,再调用addblockevent。

  }

  addblockevent{

  在一个列表里按顺序添加方块事件,但不会重复添加相同的事件(推出和收回不算相同)

  }

  tick(S世界主循环节选){

  依次调用对应方块的onblockevent received,如果它返回了true,则把一个表示blockevent的包发送到C,让C调用onblockeventreceived

  }

  onblockevent received{

  只在S执行{

  如果要伸出但是没信号,返回false

  如果要收回但是有信号,返回false,并把状态设置为推出态(同步到C)

  }

  若要推出{

  调用domove,如果domove返回了false,则返回false

  设置为推出态(同步),再返回true

  }

  若要收回{

  清除原来活塞臂的位置的方块

  把自身设置为36号方块(同步)

  如果这是粘性活塞{

  如果将会拉回的方块是36号方块,把它清除掉

  如果前面的方块是可以移动的,调用domove

  }否则,把活塞臂的位置设为空气(同步)

  }

  返回true

  }

  domove{

  如果要收回的话,把原来的活塞臂位置设为空气(同步)

  计算将要移动的方块和将要掉落的方块。如果不能移动,返回false

  把所有将要掉落的方块设置为空气(同步),然后掉落。

  把所有将要移动的方块设为空气(同步),即将移动到的位置设为一个36号方块(不同步)

  如果要推出的话,把活塞的前方设置为一个包含活塞臂的36号方块(不同步)

  }

  既然这是一个bug,我看了半天代码也没有任何思路...于是我们转变思路,采用debug的方式,从幽灵方块生成器来入手!

  这是Logdotzip的幽灵方块生成器,是最早的,也是最直观的一个。当拉杆输出下降沿时,会把钻石块以幽灵方块的形式推出,就像这样:

  不过这个东西看上去还是有点复杂。我们可以把中间这个机器拆分成左右两个部分:

  左边是G方块生成器的核心,右面只是决定了推出哪个G方块而已。

  我们发现,当拉下左边的装置的拉杆时,一个G活塞被推了出去。

  而右面的装置所做的事情呢,就是在推出两个G后(G1:C=钻石块,S=空气,G2:C=活塞,S=钻石块)把G2收回了,用了一个方法(这个方法以后再谈)消除了G2,于是只剩下G1了。所以,我们的关注点转移到了左边的装置上。

  接下来我们就是要解析左边的这个电路

  根据前文的内容,我们梳理出了这样的S时间轴。其中把向上的普通活塞称为P1,对着粘液块的活塞称为P2,推出称为+,收回称为-

  以下是电路对于活塞的操作:

  P1退激活(NTE)

  {P1激活(NTE)

  {P2激活(NTE)

  注意,P1和P2的激活顺序是不定的,但显然这并不影响幽灵方块的产生。

  接下来我们要把这个时间轴转化为活塞的行为:

  P1:EXTENDED=false(NTE)

  P1:addBlockEvent -(NTE)

  {P2:addBlockEvent +(NTE)

  {P1:addBlockEvent +(NTE)

  P1:receiveBlockEvent(BE)

  P1:EXTENDED=true(BE)

  {P2:推出(BE)

  {P1:尝试推出自己的活塞臂,但是并未成功(搞笑)(BE)

  我们发现,addBlockEvent的唯一影响就是收到BlockEvent的顺序,所以它是不需要表示的。最后那个搞笑的P1也是没有意义的。于是,我们精简成了这样:

  P1:EXTENDED=false(NTE)

  P1:receiveBlockEvent(BE)

  P1:EXTENDED=true(BE)

  P2:推出

  可以发现,在S,P1设置EXTENDED=true的时序永远比P2的推出要早。所以在S中P1不会被推出。

  那么,C是怎么操作的呢?我们将以S的时序为主线,将它向C发送的Packet标在时间轴上:

  P1:Extended=false(NTE)

  sendPacket BlockChange:P1.Extended=false(PMU)

  P1:receiveBlockEvent(BE)

  P1:Extended=true(BE)

  P2:receiveBlockEvent(BE)(上一层楼忘写了)

  P2:推出(BE)

  sendPacket BlockEvent:P2推出(BE)

  sendPacket BlockChange:P1.Extended=true(PMU)

  可以发现,因为当P1的Extended=true时,已经过了那个tick的PMU了,只好等到下一tick发送。所以P2的推出事件就抢到了P1的前面,从而先发制人地把P1推出了。

  那么粘液块是干什么的呢?C想要让P2推出,就需要让S的P2成功完成一次推出。而能黏住P1却不会被P1阻挡的方法,只有利用史莱姆块了。

  这个时间轴就是我们制作幽灵方块生成器的指明灯。只要满足这个时间轴就可以产生幽灵方块,不需要我们实际操作才能判断它是否能产生了。比如说,这个装置就是原生成器一个小小的变体:

分享到:更多

游戏信息

我的世界
我的世界类型:休闲娱乐平台:PC,iOS,安卓电脑版下载
  • 游戏大礼包
  • 手游开测表