在上一小节,我们让小猫显示了出来,这一节,我们将学会如何让小猫动起来,也就是如何制作物理引擎。
原理思考
首先,我们需要了解一般的物理引擎的运作概念。
一个物体,我们可以将其运动状态分割为两个向量,一个作为X轴速度,另一个作为Y轴速度:
在其基础上,我们可以进行关于X轴和Y轴的受力分析:
在地面时,地面给予的支撑力和“重力”相互抵消,Y轴速度为0,X轴没有任何力的作用,所以X轴速度为0。
从常规的物理知识中,我们可以知道,力的作用是不会直接转变为速度的。
对一个物体施加力,会导致物体的速度变化,如果我对X轴先施加了1的力,然后再施加-0.5的力,此时X轴的速度应该为0.5。这个0.5在下一次为这个物体施加新的力之前都不会变化。
在现实中,我们推出去的物体总是会慢慢变慢,最后停止,这是为什么呢?
这是因为,物体除了受到我们推出去的力,在滑行时与地面接触的部分一直在施加反向的力,这种因为和另一个物体摩擦而产生的力我们称之为“摩擦力”
除了摩擦力之外,还有一种力被称为空气阻力。飞机在天空中飞行时,推进器在不断施加推力,但是飞机的速度很难在进一步,这就是“空气阻力”在从中作祟。
所以,在我们的游戏中,总是会出现四种不同的力:
- 重力
- 摩擦力
- 空气阻力
- 玩家移动
其中,玩家移动的力可以是基于摩擦力的,即必须在地面上才能改变方向,鲜明的例子有:
- GTA5
- PUBG
这种玩法更多是趋近于真实性。
当然,玩家移动的力也是可以独立出来的,即不需在地面上也能改变方向,鲜明的例子有:
- 超级玛丽奥
- 空洞骑士
这种玩法更多是趋近于趣味性。
碰撞检测
在受力分析之外,我们还需要进行碰撞检测,为了防止角色 卡进后室 卡进墙里,这一步是必须的。
X轴
首先我们还原一下角色碰到墙壁的情况:
因为scr的碰撞检测并不能预测下一帧,所以当检测到碰撞时,必然是已经有一部分碰到了墙壁,所以此时我们应该在一帧之内往后退,直到碰撞箱不再碰到墙壁。
但是!!!(没错凡事都有但是)
不妨让我们换一种情况来考虑:
我们假设碰到的不是一个墙壁,而是一个斜坡,如果只是碰到就返回的话,碰到斜坡也会被返回,而在游戏中,这是不可取的。
所以我们需要为斜坡定制一套上坡的流程:
至此,我们碰撞检测的流程就变为了:
Y轴
接下来,就是Y轴的判断。
因为大部分判断我们都在X轴的判断中处理完毕了,所以Y轴只需要处理重力的情况了。
在物体下落时,先判断有没有碰撞,碰撞就回到没碰撞的状态。
因为重力是一个连续的力,所以他应该是在一个循环内不断使速度增加的效果,并在某个速度点与空气阻力形成平衡。
所以我们的下坠应该是在速度达到极限之前一直增加一。
逻辑如下:
贴墙判断
接下来的步骤,就是思考小猫派对如何做到的贴墙了。
首先观察游戏,贴墙拥有两个前置条件:
- 跳起来
- 贴墙
所以贴墙的算法就相对简单了。
使用一个变量判断是不是跳跃,然后再X碰到墙壁并确定不是上坡后,开启贴墙状态就好了:
当我们在贴墙后,我们会发现,在贴墙的时候,我们的下落速度会减慢。同时,我们可以在无需按下W的情况下,只是重新移动,从墙面蹬起。
所以我们在贴墙后,不会禁止X轴的移动,而是检测当X轴大于某个值,被判定为移动后,为Y轴施加一个向上的力,让玩家看起来像蹬墙跳。
至此,X轴的逻辑变为了:
Y轴还需要增加一个站立检测,检测到站立就停止贴墙状态。
但是这样的判断还有一个最大的问题,那就是当你进入了贴墙状态,从墙面滑落到半空中,你仍然处于贴墙的状态,从而导致在空中蹬墙跳。看起来就和左脚踩右脚上天一样。
这当然是不行的,可是在酷可的小猫派对中,并没有修复这个BUG,但是既然要复刻,那就做到完美,所以我们来思考一下应该怎么修。
我们来分析一下在贴墙时和出BUG时有哪些判断上的区别:
贴墙:
- 跳跃中
- 碰到墙壁
出BUG:
- 跳跃中
- 没有移动
如上,我们可以发现,在贴墙时,你是可以朝着墙面移动的,但是在BUG时,你不能移动,一移动就会退出贴墙状态。
但是移动很难判定,所以我们用第二种判定方法,那就是没有碰到墙壁,当变量记录在贴墙,但你没有碰到墙壁时,那多半就是在BUG的状态。
如此一来,我们就需要再改一下X轴的逻辑了:
完美,如果你完全理解了的话,就让我们进入编写积木的环节吧!
当然,如果你未能理解,也无需担心,因为我们下一小节将会进行代码的编写!
<iframe
width="100%"
height="800px"
scrolling="no"
src="https://www.ccw.site/embed?id=WhiteCat101/baimao/Lec2/02&type=comment"
title="{小猫2-思考如何移动}"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
scrolling="0"
></iframe>