继续上次的游戏碰撞检测的主题,上次我们通过方法 testCollision 来检查两个物体是否碰撞,如果发生碰撞就返回 true 否则返回 false。这种检测可用于判断角色与子弹或与怪物接触时,但是如果一个运动的角色与墙壁呀或与者障碍物接触时,角色是无法穿过障碍物,或停留在障碍物内部,角色会退回一个位置。角色碰撞后回到什么位置是今天重点讨论的内容。
这里会用到数学中学到的向量概念,向量是有大小和方法。我们用一个向量表示运动角色与障碍物中心的连接线,有点不准确,为了便于大家理解,暂时看作一条线段,如下图(连接绿色和蓝色小块中心的连线)
红色线段两端分别是角色(绿色)和障碍物(蓝色)的中心点。如果这条线端在坐标的 x 轴和 y 轴上都会有投影。.
vector_x 和 vector_y 分别代表向量在 x 轴和 y 轴上的分向量。
现在注意一下,在下图中,当绿色小块从左侧向蓝色小块方向运动,当碰撞时 vector_x 应该大于 vector_y。从其他三个方向向蓝色小块运动碰撞的场景,大家可以自己尝试画一下,推一下其中规律。
不难看出当 vector_x 大于 vector_y 说明绿色小块是从重左右两侧来与蓝色小块进行碰撞。当 vector_y 大于 vector_x 说明绿色小块是从重上下两侧来与蓝色小块进行碰撞。所以我们可以抽象出四个象限,通过绿色小块运动方向和 vector_x 和 vector_y 关系可以划分为四个区域。
通过上面总结,我们可以很好理解下面的两个图,虚线小块是蓝色小块碰撞时快照,绿色小块表示碰撞后弹回的位置
上代码
在 Rectangle 中创建 resolveCollision 方法如下图,代码中 vector_y 和 vectory_x 平方后进行比较,为了比较其绝对值。当 vector_y 大于 vector_x 并说明是上下方向上进行的碰撞,vector_y > 0 表示从下方向上进行碰撞所以会停止在蓝色小块下方。其他三种情况可以自己看一看,就不一一说明了。
然后我们在 if(palyer.testCollision(tile)) 中调用 resolveCollision 方法,说明其前提条件是两个小块已经发生碰撞。
今天就到这里,下周我们回到 mario 游戏开发,将这些理论应用到开发中进行实践。
网友评论