这是2D游戏的数学问题。
Given 2 object ( 2 car, 2 tank, 2...), for each object i know:
1. X, Y
2. Actual Speed
3. Degree of movement (or radiant)
如何计算2对象的碰撞“效果”
PS:
我使用这个简单的公式“移动”对象,每次勾选我的“游戏循环”:
ychange = Math.Sin(radiant) * ((carspeed / xVar));
xchange = Math.Cos(radiant) * ((carspeed / xVar));
(其中xVar是一个“乘数”,让我的车在屏幕上变得更慢)
对于碰撞的“第一个”物体,如果我在该公式前面添加一个“减号”( - ),我可以模拟第一个物体的良好“反弹”但不能用于第二个物体。 / p>
所以我的问题是为第二个物体计算好(不完美!)和更逼真的“影响效果”的方法。
感谢您的帮助
答案 0 :(得分:3)
几个月前我实施了斯诺克游戏。我使用以下代码使两个球碰撞。请注意,它们不是边界框。
此方法根据每个物体的质量,速度和角度计算得到的速度和角度。
它在我的游戏中起到了一种魅力。
float dx = b1->x - b2->x, dy = b1->y - b2->y;
float d = sqrt(sqr(dx) + sqr(dy));
float vp1, vp2, vx1, vx2, vy1, vy2;
vx1 = ballSpeedX(b1);
vx2 = ballSpeedX(b2);
vy1 = ballSpeedY(b1);
vy2 = ballSpeedY(b2);
vp1 = vx1 * dx / d + vy1 * dy / d;
vp2 = vx2 * dx / d + vy2 * dy / d;
float distance = sqrt(sqr(dx) + sqr(dy));
// Unit vector in the direction of the collision.
float ax = dx / distance, ay = dy / distance;
// Projection of the velocities in these axes.
float va1 = vx1 * ax + vy1 * ay, vb1 = -vx1 * ay + vy1 * ax;
float va2 = vx2 * ax + vy2 * ay, vb2 = -vx2 * ay + vy2 * ax;
// New velocities in these axes (after collision): edmass / b2->mass);
float vaP2 = va2 + (1.0 + D_BALL_ELASTIC_COEFFICIENT) * (va1 - va2) / (1.0 + b2->mass / b1->mass);
// Undo the projections.
vx1 = vaP1 * ax - vb1 * ay; vy1 = vaP1 * ay + vb1 * ax; // new vx,vy for ball 1 after collision.
vx2 = vaP2 * ax - vb2 * ay; vy2 = vaP2 * ay + vb2 * ax; // new vx,vy for ball 2 after collision.
b1->speed = sqrt(sqr(vx1) + sqr(vy1));
b1->angle = acos(fabs(vx1 / b1->speed));
b2->speed = sqrt(sqr(vx2) + sqr(vy2));
b2->angle = acos(fabs(vx2 / b2->speed));
此代码是用纯C编写的。 我存储移动数据的方式与您的相同。变量b1和b2是球。
我认为代码本身并不难理解,但物理并不是微不足道的。
希望它有所帮助!
答案 1 :(得分:2)
最简单的方法是让它们交换速度。如果它们完全相同,这是有道理的。
如果你想做更多,你可以为一个参数选择一个随机值,该参数将决定它们是否有掠过的碰撞(几乎不接触)或完全撞击,或介于两者之间。您还可以模拟两个物体的不同质量(当摩托车撞上货车时,卡车不会发生太多事情)。最后,你可以发生只有部分弹性的碰撞;也就是说,它们不会像橡皮球一样反弹,它们会紧缩,并且会失去一些能量。这些将需要一些数学和对物理的理解。
答案 2 :(得分:1)
以下是对物理学的解释:
你有四个未知:碰撞后每个球的x和y速度。
所以你需要四个方程式。
x和y中的动量守恒给出两个。妈妈= mv
保留动能给出了第三个; Ke = 1/2 * mv ^ 2(之前和之后)
除此之外,相对性原理可以用来假设一个球最初是静止的,比如uB.x = uB.y = 0
在冲击时,冲动必须沿着每个球的中心之间连接的线发生。因此,如果您假设球B最初处于静止状态,那么现在它将朝着该线的方向移动,因此您可以表达vB.y = f + g * vB.x,从而将未知数减少到3。
三个未知数,三个方程式。好极了!
如果碰撞不是弹性的,那么它取决于你想要模拟的准确程度。像Ke_after = 0.99 * Ke_before之类的东西,然后把它扔进数学。
我把它作为练习留给读者来推导出完整的方程式。
答案 3 :(得分:0)
radiant
?