首先, 自己程序很菜, 所以从最初的写法到最终走了很多弯路, 网上的资料也比较少, 所以还是把想法分享出来
首先说一下前提背景, 我做的是一个球类的游戏, 有个功能是预判短位置和虚拟路径的显示
1.用非box2d来手写这个, 引擎当然就是自己写的要你命三千, 各种问题次鞥出不穷, 有问题还不好复现, 这个瞄准是有, 精度就不敢恭维, 原理上就是递归运算实际飞行的整个路程, 通过角度来定位, 然后每移动一个位置, 通过精度来调整位移的距离, 来增强检测的准确性
结果: 越准确就越需要更多运算, 最后精度大概估计在80%吧, 还算满意
后来用box2d来改写游戏, 从下面开始就是各种苦逼尝试
2.建立一个幽灵球(感应器true), 和正常球一样的发射角度, 调整发射速度, 来加快整个路径的形成
结果: 越速度快越快速完成路径, 更越容易穿透其他球, 导致出现bug, 如果可以忍耐这渣速度的话也可以接收, 精度(100%~0%) 子弹状态开启, 如果碰撞是计算的很完美的, 但是穿透就是错误, 无法接受错误和反应速度
3.射线, 建立一个接近于无限长的射线, 通过射线和整个引擎内的刚体遍历, 得到最近的刚体碰撞位置(得到的fraction越小就越近), 然后通过运算可以让其是否反射或直接终止
结果: 发现反射的时候射线是以一个点来实现的, 但是球是有半径的, 失败....
4.涉嫌组, 不放弃, 觉得这个方法可行, 于是建立了一个射线组, 来组成球的半径, 三条射线分别在左侧 右侧, 和中间, 但发现如果变了个角度, 射线之间的间距会变小, 于是让三个射线的起点垂直于初始点平行分部, 但是这样又发现墙壁反射一塌糊涂
结果: 将三条射线放于水平, 然后根据角度来加大射线间的距离, 来保持 平行方向的间距是固定的值(R/cos(a)), 这样到墙壁, 如果任何一个射线反射, 那么其他射线也跟着反射, 但是问题又出现了, 三条射线到其他球的时候, 是平行的, 不是球面的, 如果我改变初始的位置为球面的点, 墙壁反射又乱了, 完全陷入崩溃的边缘
结果: 这个方法如果不反射, 准确率大概在60% , 反射后准确率(60%~0%), 而且由于射线是可以很细, 穿透很容易, 这样缝隙过去的进行计算就又出现诡异问题
这时候我无奈的上网找问题:
找到这个权威的box2d基础网站:
https://www.iforce2d.net/b2dtut/
上面有咱们国人的翻译教程
http://ohcoder.com/blog/categories/box2d-tutorials/
大牛不错, 留了email, 迅速写信给他, 我以为收不到, 结果2小时就给我回复, 大致内容:
我已经不再做涉及box2d的项目很久了, 不过给你个参考地址:
https://www.iforce2d.net/b2dtut/projected-trajectory
非常感谢后继续研究, 恩 不错 正是我想要的:
5. 也是同样通过射线, 不过这次射线并不是趋于无限长, 也不用自己去递归, box2dworld->RayCast()去处理它就好了, 直接像碰撞事件一样绑定它就好
注意的是需要在侦听函数ReportFixture内, 如果已经得到了自己想要的对象, 就直接返回0, 如果返回大于0的值, 则此raycast还会遍历去查找, 我就不需要了, 下面讲为什么不需要
直接做个b2vec2的点, 让它运动起来, 这里需要微分, 如果需要精确的处理做到1/60s, 我只做了1/10s就足够了, 并当点更新位置的时候, 以这个点为圆心, 向四周做射线, 射线长度为球的半径, 如果碰撞产生并合格, 则第一时间处理, 因为是微小射线, 而且是微小位移, 完全没必要去处理最近碰撞点这个问题
结果: 步长越小, 精确越高, 但是由于需要瞬间走很长一个距离, 所以, 效率会很低, 不需要太精确, 向外射线的个数也不需要太多, 我这里只做了12条, 也许以周长方向做12条射线更精确一些. 准确率90%+
我的问题迎刃而解 当当当当~~~~