平台游戏中走与跳的实现

发表于2019-05-27
评论1 5.1k浏览

内容简述:

        平台游戏中,如何在动作操作方面达到《Celeste》,《死亡细胞》等作品那样的效果(手感),单纯使用物理引擎是比较难做到的,因为我们需要一些反常识的运动效果,而这些效果可能是多种运动组成的,为了更精细的控制物理运动,需要对每一种动作的物理运动做特定的建模与调参。

        本文会针对平台类的游戏,针对走路,和跳跃这两个行为,从实现原理上做一些解释,为了更清晰的表述,文中会使用伪代码来解释。读完文章,你会了解走,跳的一种实现思路。话不多说,让我们开始吧。

 

简化:

        平台类游戏,最常见的物体会有,地板,墙,角色这三种,首先我们需要简化其几何模型,因为这会大大提高后边物理计算的效率,也更直观,更容易理解。

yQDcPl0KTzwXiZbRPJ8H.png

 

游戏循环:

        游戏循环,几乎所有的游戏都有一个叫游戏循环的部分,这部分代码会被一遍一遍的执行,直到游戏结束。功能上通常包括收集用户的输入,更新所有物体的状态,渲染成图等。逻辑如图 

PRpdovrnx9ciCSRhs2hD.png

        每一个Update函数负责改变游戏内所有物体的信息,后边的Render会根据数据生成一张图片,也就是常说的一帧。这篇文章所讨论的问题就是:在Update函数中,如何计算出每一帧玩家的位置。

 

走:

n2YSR0jJBHENdZ91YZyG.png

        从上图中可以看出来,物体当前帧的位置可以根据上一帧的位置来计算出来。

j3KmBDhtoXOeEGwqtOaV.png

        第3行用来计算偏移距离,即:偏移距离 = 运动速度 x 时差。

        第4行用来计算当前帧物体的位置, 即:当前帧物体的位置 = 上一帧物体的位置 + 偏移距离。

        利用上边的实现,我们已经可以使角色运动起来了。

hfcjIWCBGt7dFapJf7dI.gif

 

加入墙体:

        当加入墙体后,需要对墙体做特殊处理,以保证角色不会直接穿过墙体。

ynJS3oifIqokzb45ei7C.png

        用线段A去和外围的世界做碰撞检测,如果有交点,那么则代表碰撞到物体,需要修正偏移距离。线段A的一个端点可以选择上一帧物体的中心,另一个端点可以根据当前速度,时差来计算出。那么,代码就变成了这样:

KUp0WePuhGI5ZV91SmOA.png

        新加入的代码:使用线段与场景内的物体进行求交检测,如果有交点,更新偏移距离。利用上述代码,角色将会被墙壁挡住。

fhJuFEJJeS0H4N70lc9M.gif

 

处理坑:

        如果用上述代码来让角色走过一个坑洞时,角色会并不会掉落下去,而是直接走过,所以需要特殊处理有坑洞的情况。思路是,首先检测坑洞,如果没有检测到,则保持水平行走,如果检测到坑洞,则切换物体为掉落状态。

0gxq9n0F8Ij4tnliC3it.png

        检测坑洞具体的方法是向下做一个线段进行碰撞检测,如果没有碰撞到物体,代表下边就是一个坑了。贴出加入坑洞处理的代码。

jZB5dfzrnd2aVxly6GUD.png

        第3行添加了状态检测,角色的状态除了走路之外,还会有跳跃,冲刺……等其它状态,所以在此我们添加一个变量state用来追踪当前玩家的状态,以区分和管理角色的行为。

        第10-14行:利用垂直线段向下进行碰撞检测,如果有交点,那么修改垂直偏移距离。

        第16行:如果检测到坑洞,则改变角色当前状态为“下落”

 

下落状态:

        下落是从跳跃的最高点处开始向下,直到落地的这个间隔。或者是在走路时遇到坑洞后,掉落的这个过程。下落过程中,处理情况和行走是非常的相似的。

a0d1c12mVOblcEdqnx0z.png

        第16行,在行走的过程中,如果向下方的碰撞测试没有检测的地面,这时需要改变为下落状态。

        第20-23行,在下落的过程中,检测横向的墙面,如果有碰撞,需要修正偏移的距离。

        第25-30行,在下落的过程中,如果向下方的碰撞测试,检测到了地面,需要修正垂直偏移距离。

jYu7QaEzbYAFtwFMWCoZ.gif

 

起跳:

        起跳是从离开地面到最高点这段过程,当收到玩家指定时,进入跳跃状态,代码如下:

4aVGhnppJXHOQeGmyMMw.png

        第39-41行,在起跳的过程中,如果达到了跳跃的最高高度,那么应该切换到下落状态。

        第43-49行,和前边的代码行为是类似的。

rmYl9PhPslS1VsgW5F75.gif

总结:

通过上述的描述,我们已经可以实现出平台游戏中走与跳的行为了,并且可以方便的扩展出更多的运动效果,比如:

  • 走路的滑动
  • 落地弹一下
  • just-in-time jump
  • 碰到墙上反弹
  • 走路时加速
  • 加速跳
  • ……

 

为了用尽量短小的篇幅说明问题,文中删减了一些和物理实现无关的问题,比如动画管理切换,用户输入采集等……文中的截图,均是采用上述方法实现的。

感谢 :文中设定和动画由 画师AOMZER 友情提供

 

扫一扫,内有彩蛋

Yuw6WOvVheYuP7IcXDG8.jpg
  • 允许他人重新传播作品,但他人重新传播时必须在所使用作品的正文开头的显著位置,注明用户的姓名、来源及其采用的知识共享协议,并与该作品在磨坊上的原发地址建立链接
  • 可对作品重新编排、修改、节选或者以作品为基础进行创作和发布
  • 可将作品进行商业性使用

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引