第一节 圆形碰撞箱
下面,我们来制作实体间的圆形碰撞箱的效果:
- 人物之间存在圆形碰撞箱,靠近时会弹开;
- 贩卖机、炮台、建筑等也有圆形碰撞体积。
实现思路
下面我们来看看如何实现这种圆形碰撞箱效果。
- 如下图。绿色是玩家碰撞箱,坐标 (x0, y0),半径 r;红色是障碍碰撞箱,已知障碍坐标(x1,y1),半径 R。如何判断两者发生了碰撞?
我们可以计算两者距离 d:
- 当 d > R + r,两者没有碰撞;
- 当 d = R + r,两者恰好发生碰撞;
- 当 d < R + r,两者相交,发生碰撞。
因此,通过判断 d < r + R,说明两个圆发生了碰撞。
- 第二个问题:碰撞后,如何让玩家回弹一段距离,直到刚好解除碰撞(刚好相切)?
答案是:回弹距离 d0 = R + r - d。其中 R+r 是最终距离,d 是开始时的距离。
- 第三个问题,已知回弹距离 d0,如何分别计算 x、y 坐标回弹的值: dx、dy?
如上图,根据相似三角形的比例关系,有:
求出 x、y 坐标反向移动的距离:
dx = d0/d * (x1-x0)
dy = d0/d * (y1-y0)
这样,就可以求出 x、y 的回弹值,dx、dy
- 总结来说,检测玩家和其他碰撞箱之间碰撞的思路是:
- 遍历所有其他碰撞箱;
- 对每个碰撞箱,计算玩家到它的距离 d。如果 d < R + r(两者半径和),说明发生了碰撞;
- 如果发生碰撞,求出回弹需要反向移动的距离 dx,dy,让玩家的 x、y 分别反向移动 dx, dy
代码实现
- 首先新建一个列表:碰撞箱ID列表,用于记录哪些实体有碰撞箱。
- 对于有碰撞箱的实体(例如玩家、人物、贩卖机等),实体生成后,将自己的 ID 加入碰撞箱列表;当实体删除时,再将 ID 从碰撞箱列表移除。
例如,给玩家添加碰撞箱,并设置碰撞箱半径:
玩家死亡后,删除玩家碰撞箱(否则玩家碰撞箱会残留在舞台上)
比如,可以给贩卖机设置碰撞箱,并设置碰撞半径:
同理,给人物设置碰撞箱,当人物死亡后再从列表删除。
- 制作如下全局积木——检测和其他人的碰撞,实现下面的功能:
- 遍历碰撞箱列表(跳过自己,自己不和自己碰撞);
- 对于每个碰撞箱,计算距离,如果距离 < 两者半径合,则认为发生了碰撞。
- 发生碰撞后,x、y 分别回弹一段距离:
- 顺带一提,上面的代码是直接完全弹开,显得碰撞很“硬”,也可以给下面的系数乘以 0.5,这样每次只弹开一半的距离,会显得更有弹性:
- 我们还可以添加发生碰撞后,给对方造成伤害的代码(可以实现载具撞人等效果):
- 最后,给玩家、人物添加下面的代码,就可以实现圆形碰撞箱效果了:
上一节:本课简介
下一节:02 关卡3
<iframe
width="100%"
height="800px"
scrolling="no"
src="https://www.ccw.site/embed?id=STG303/Arkos/Lec7/02&type=comment"
title="{射击课高级篇-第七课-02}"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
scrolling="0"
></iframe>