爆发桨与角度碰撞
本文关键字:碰撞 爆发 | 更新日期: 2023-09-27 18:24:22
我知道互联网上有很多关于这方面的东西,我已经看了很多,但我就是无法让它与我的代码一起工作。我知道它背后的数学原理,但又很难把它变成代码。我有两个球的速度变量float xSpeed, ySpeed
。两者都等于3(或者-3取决于碰撞-我只有基本的碰撞atm)。我还使用了一个矩形来表示球ballRect
和球拍paddleRect
。我正在更新位置:
ballRect.X += xSpeed;
ballRect.Y += ySpeed;
我找到了一些代码,并试着自己做,但它们真的很bug。一个人(我认为)会在第一次击球时发挥作用,但当他下一次击球时,它会粘在球拍上。
double relativeBallPos = (paddleRect.X + ballRect.X);
double ballVelx = xSpeed;
double ballVely = ySpeed;
double angleRads = Math.Tan((ballVelx / relativeBallPos));
double angleInDeg = angleRads * (180 / Math.PI);
double angleOfReflection = (angleInDeg * 2);
ballVelx = ballVelx * angleOfReflection;
if (ballRect.X + (ballRect.Width / 2) < paddleRect.X + (paddleRect.Width / 2))
{
xSpeed = (float)-ballVelx;
}
else if (ballRect.X + (ballRect.Width / 2) > paddleRect.X + (paddleRect.Width / 2))
{
xSpeed = (float)ballVelx;
}
(这是以一个(可能不正确的)角度发生的,只是在第一次命中后直接上升)感谢您的帮助:)
如果你的球与任何水平阈值(砖块或球拍的水平面)相交,则取ySpeed
。如果它与任何垂直阈值相交,则否定xSpeed
。好了,现在你有了一个功能性的突破游戏。
当球击中球拍时,你可以根据碰撞的位置来改变球的角度,使中心成为全反射(即否定ySpeed
),xSpeed
得到与中心距离的因子(正或负),从而增加更多的抛光度。
是的,你看到的是完全正常的,如果你的物体移动得很快,而游戏节拍速度很慢,你可能会出现一些小故障,比如卡住球拍,甚至完全错过球拍,然后直接穿过。
错过球拍的解决方案是提高游戏节拍速度,即更频繁地处理游戏移动。
球对桨的粘性可以通过及时回滚物体运动来缓解。例如,对象A和B在某个时间点发生碰撞。如果你简单地反转它们的X和Y速度,你可能会在下一个时间点再次碰撞,所以你会再次反转它们的速度,以此类推,这看起来就像卡住了一样。它有时会卡在一个唯一的轴上,所以它会在桨上滑动,然后直接向下,这只是同一问题的另一个副作用。
如何进行回滚?你知道A在哪里移动,假设B是一个桨,所以它是静态的。你知道A此刻正在和B相撞。你可以计算一个a运动的矢量,并通过反转的矢量将a滑回时间。例如,如果屏幕的左上角是(0,0)
,而A以X=+10,Y=+10
的速度移动,则您会将其向后移动整个步骤或一小部分(取决于您想要的复杂程度),也就是(-10,-10)
或其一小部分。您可以使用相交矩形来计算精确的值,并且只移动足够的距离,使对象几乎不接触。
理想情况下,你应该将矢量反射出击球表面(使用物理学,即击球角度=反射角度),在应用新的速度之前,以不与球拍碰撞的方式移动球。为了简化,你可以假设你的撞击面是水平的,只是一条直线,所以你的反射公式非常简单。
这里很好地涵盖了这个主题(尽管使用XNA,但同样的原理适用):
- 矩形边界框碰撞后卡在墙上