Unity 实现类似 QQ泡泡堂一样平滑行走的 基于Tile的移动算法

来源:互联网 发布:美白乳液推荐知乎 编辑:程序博客网 时间:2024/04/29 23:12

最近被策划要求,实现平滑行走的炸弹人移动。


参考:http://www.7k7k.com/swf/129418.htm


我不是给这厮做广告,也不觉得这东西好玩,只是研究这算法还算好玩。一开始我做的时候,走进了一个误区,要炸弹人走到离中心线很近的距离,才可以转弯,然后做位置矫正,结果移动不平滑,很生硬。


后来看了人家游戏怎么做的(小策划一直不肯给我看这个,是不是怕被我知道山寨目标呢?嘿嘿嘿)

发现原来还有更好的解决方案,那就是,当人物未达到中点,但是已经迈到下一个格子的时候,做操作补正,如图所示。




旧的思路是只有玩家在接近中线时才可以转弯,这明显很难做到,参考了人家游戏的做法之后,我开始了反向工程(山寨算法),花了大约一天时间,研究明白了其中的道理。

如图,当玩家中点在路1的时候,肯定是不能右转的,因为灰色障碍挡住了玩家的路线,而当玩家中点在路2时候,允许转弯,但是明显,不能让玩家脑袋

插在墙里移动,因此必须先修正方向,让玩家的中点对准路2的中线之后,才允许他转弯。


这里不给代码了,只是说一下思路和要点:

【1】能否移动到目标方向(操作方向)指向的格子,完全取决于master_stand_on

是的,做炸弹人这种游戏的时候,除了在格子正中央时,炸弹人总是踩在两个格子上的,并且,炸弹波及两个格子时,都会记录伤害。因此,

我用两个引用指向这两个格子,其中炸弹人的中心所在的格子,是其父节点,也就是master_stand_on

【2】只有在严格中点上,slave_stand_on为空

【3】当离开严格中点时,必须立刻计算slave_stand_on

【4】当slave的中心距小于master的中心距时,必须立刻交换master与slave,并且更改Transform.parent
【5】当master在操作方向上,允许移动,而slave在操作方向上,不能移动时,需要计算修正方向。

这个比较难解释,直接给段代码吧

  public EDirection GetAdjustDirection( EDirection op_direction ) 
        {
            //如果恰好在中点,纠正方向,就是原始方向
            if (is_on_center ) 
            {
                return op_direction;
            }


            if (slave_stand_on.y == master_stand_on.y && (op_direction == EDirection.UP || op_direction == EDirection.Down) )
            {
                if (slave_stand_on.GetNeibhouor(op_direction).CanMoveIn(this) == false)
                {
                    if (master_stand_on.x < slave_stand_on.x)
                    {
                        return EDirection.Left;
                    }
                    else
                    {
                        return EDirection.Right;
                    }
                }
            }


            if (slave_stand_on.x == master_stand_on.x && (op_direction == EDirection.Left || op_direction == EDirection.Right))
            {
                if (slave_stand_on.GetNeibhouor(op_direction).CanMoveIn(this) == false)
                {
                    if (master_stand_on.y < slave_stand_on.y)
                    {
                        return EDirection.Down;
                    }
                    else
                    {
                        return EDirection.UP;
                    }
                }
            }


            return op_direction;
        }
【6】不过中点时,物件移动方向,取决于修正方向。而不是操作方向。除非他们一致。
【7】任何经过中心点的移动,都必须被拆分成两个移动,哪怕方向不改变,移动到中心点,
必须触发进入中心点事件,以保证离开中心点时触发离开中心点事件,这是整套算法的核心。

这个是所有算法最重要的核心:

表面上看,只要预测 当前LocalPosition的xy值和预测下一帧LocalPosition的xy值符号是否发生变化即可,然而实质上,光是这样还不够的,最好同时判断上一帧的xy符号值和这一帧的符号值,取或,才能得到正确结果。

【8】回到中心点事件中,必须将slave_stand_on设置为空。
【9】如果经过中心点并转向,前半部分移动,方向取决于纠正方向,而后半部分,取决于操作方向

照着这个思路,实现一个炸弹人行走的流畅算法,应该很容易了,具体怎么做自己思考一下才有意思,就不上全部代码了。



1 0