Intro:
有个问题经常被提及到:“当一个物体被抛起或者发射到空中时,我要怎么知道它的运行轨迹
1.它的行进路径是怎样的?
2.它可以达到的最大高度
3.物体会以多快的速度达到预想的高度
4.它会碰撞到什么东西
5.它会反弹到什么?
下面的情况下需要知道物体的运动轨迹,当玩家控制一个抛射的物体时,玩家想要知道它的虚拟轨迹来显示它接下来的运行情况,而且当电脑将要去操纵一个物体时,也需要一个虚拟的运动轨迹来让下面的事变得清晰。
有两种办法可以预先知道物体的运行轨迹:一个是用公式去计算接下来的物体位置,或者用box2d的世界来模拟下面的步骤,下面先向我们快速地浏览下这两个办法:
用公式的办法最明显的优点是它需要更少的运算时间,而且不要求复杂的世界状态,但是它最明显的缺点是,如果有另外一个动态的物体在这个世界里面,用公式的办法就不能准确地回答下面两个问题:它会碰到哪个物体,而且长远来看,我们要知道世界里面所有的运行物体在后面的位置。
另一方面,用全模拟世界的方法确实可以解决上面所有的办法,因为它知道屏幕里面所有的物体在接下来的位置,但是它些信息的得来是需要花费更多的时间。首先它肯定是要执行更多的操作任务,当用户更改抛物线的轨迹,或者鼠标移动更新了。
(译注:里面叭啦叭啦一大堆就是讲的是用公式的好处)
所以这篇文章就只讲插入公式的办法来预先显示运动的轨迹。只要记住,如果你想知道这个运行的运行抛物线与其他所有动态物体的交互,那么你就需要用世界来模拟所有的场景物体,但是在大多情况下,我想用公式的办法就可以很好的显示一个物体的预先轨迹或者用来给【AI】物体带来一个智能的判断。
在我们开始讲解之前,我们必须得认识到的是,这种公式的办法只适用于用一个定长的时间来做。
The formula
我们长话短说,这个抛物线的公式是:
说明:
我看到很多人很想知道,为什么不直接给他们一个期望的结果,我想是因为他们忽略了一个很重要的点,那就是每一个在box2d里面的物体在时间步上面都是一个分离开来的运行,你不能用一个确切的时间值插入到这个公式来计算一个位置值。
Drawing a projected trajectory
我们来看第一段代码: b2Vec2 getTrajectoryPoint( b2Vec2& startingPosition, b2Vec2& startingVelocity, float n )
{
//velocity and gravity are given per second but we want time step values here
float t = 1 / 60.0f; // seconds per time step (at 60fps)
b2Vec2 stepVelocity = t * startingVelocity; // m/s
b2Vec2 stepGravity = t * t * m_world->GetGravity(); // m/s/s
return startingPosition + n * stepVelocity + 0.5f * (n*n+n) * stepGravity;
}
接下来我们要探讨的问题是:
What will it hit?
这里面主要就是用raycast就可以了。How high will it go?
它会到达多高,