

其实这东西应该是元旦写的,但是emmm懒癌发作拖到了现在.
关于Dual collosion,是由国外玩家发现的,一种透过刺来实现贴墙的操作,上面gif下落初始align为2,在下落过程中贴到了被刺遮挡住的墙将align变为了0.
这东西我研究了一会后发现是跟DT,BH一样的引擎bug,具体bug出处在player中与block的碰撞事件里面.依照玉兔引擎的代码顺序,kid在与block碰撞之后,先进行水平方向碰撞代码,再执行竖直方向碰撞代码.不想看解释只想看怎么做游戏的直接拉到最后就行了.
在解释具体怎么实现的时候,需要了解一个东西.

GM事件执行顺序的官方解释
一般的引擎中,给player水平速度是在step(正常步事件)里面,竖直速度则是由重力控制一直存在,在step执行结束,即赋上水平速度之后,gm将player移动到了新的位置.那么看图:

dual成功的前一帧
在dual成功的前一帧,player的碰撞盒位置属性是上边界坐标为289,高于需要贴的墙的下边界,由于player贴了上面的墙,所以与右墙距离只有1,下边界+下落速度为329.4,大于下面墙的上边界327.于是你在这时候按右,给player赋上3的水平向右速度.那么按照上面顺序,gm下一个执行的动作是将player放入新的位置,即player像右移动3像素,向下移动10像素(这时候Vspeed为10).由于第三块砖与第一块砖的横坐标是相同的,所以此时player是下半身陷入block里面的.但是由于block的solid属性,player此刻会弹回原来的位置.即上图所示的位置,但是由于前一刻陷入了第三块砖中,会触发player中与block的collision事件.我们来看代码:

横向
首先是横向开始的,此时hspeed为3,grav为1.执行 move_contact_solid(0,abs(hspeed));即向右贴,直到贴到solid即第二块砖,此时贴墙行为已经完成了.那么来看Y方向上的.

竖向
此时x已经被上述行为刷新,为新位置,即向右移动了1像素.那么此时!place_free(x,y+vspeed)就为真,执行move_contact_solid(270,abs(vspeed));即向下移动直到碰到一个solid物体即第三块砖.
执行完之后,你就会发现,本来player是碰到了刺的,但是由于速度以及碰撞代码的关系,在执行kill脚本之前,player被下面的砖块拉出了死亡区域,逃离了死亡判定,bug就由此产生.
为了验证这个,我改变了一下横向与竖向的先后顺序,结果看gif

改变碰撞顺序之后的结果
但是此时发现了新的bug,gif中很明显在本来应该完成dual collision的地方,player出现了滞空问题,不知道为什么我就看了一下kid的水平速度.

水平速度为0
解释倒是能解释,改变顺序之后,player被弹回之后,由于移动已经结束,而且竖直下方没有block来拉player,所以竖直方向位置不变,但是至于为什么水平速度变为0我就不太清楚了.
简单来讲,要用dual collision做游戏,只有两个注意点,首先player与block的距离为1或者2,3及以上无效,其次,单帧内,player的位置加上水平速度能贴到墙以及位置加上竖直速度能脱离死亡区域的同时能碰到脚下的一块砖.