我有一个弹跳球应用程序,我必须延长它以防止球重叠。
当球与另一球重叠时,它们应该像现实一样移开。
我必须扩展给定的MoveBall
方法:
private void MoveBall()
{
prevX = x;
prevY = y;
x += xVelocity;
y += yVelocity;
// Is there too closed ball?
foreach (Ball ball in parentForm.balls)
{
distance = Math.Sqrt(Math.Pow((double)(ball.prevX - prevX), 2) +
Math.Pow((double)(ball.prevY- prevY), 2));
overlap = ((radius + ball.radius) - distance);// +ball.radius;
if (ball.id != this.id &&
ball.id != lastID &&
overlap > 0)
{
lastID = this.id;
if (xVelocity > 0) // roading right
{
xVelocity = -xVelocity;
x -= xVelocity - ball.xVelocity;
}
else if (xVelocity <= 0) // roading left
{
xVelocity = -xVelocity;
x += xVelocity + ball.xVelocity;
}
if (yVelocity > 0)
{ // going up
yVelocity = -yVelocity;
y -= yVelocity - ball.yVelocity;
}
else if (yVelocity <= 0) // down
{
yVelocity = -yVelocity;
y += yVelocity + ball.yVelocity;
}
}
}
// ***********************************************
// ***************** END MY CODE *****************
if (x > parentForm.Width - 10 - (radius) || x < 0)
{
if (x < 0) x = 0;
if (x > parentForm.Width - 10) x = parentForm.Width - 10 - radius;
xVelocity = -xVelocity;
}
if (y > parentForm.Height - 40 - (radius) || y < 0)
{
if (y < 0) y = 0;
if (y > parentForm.Height - 40) y = parentForm.Height - 40 - (radius);
yVelocity = -yVelocity;
}
}
x,y,xVelocity,yVelocity,radius,prevX,prevy声明为int。
重叠,距离为双倍。
当2重叠时,它们会卡住。为什么?
不幸的是,我无法上传所有源代码,因为有很多模块。 我正在使用Visual C#Express 2010。
答案 0 :(得分:2)
由于没有明确要求提问,我将假设“为什么球会粘在一起?”这个问题。
您只在源代码中显示了一个循环,这还不够;-)要检查所有可能的冲突,您需要检查n *(n-1)/ 2个可能的冲突。这通常用两个循环完成。你必须采取谨慎的措施,以避免两次处理相同的碰撞。
您的球卡住的原因是您多次处理相同的碰撞。例如,两个球完全水平碰撞:左边的球速度为5,x位置为100.另一个球的位置为110,速度为-6。发生碰撞时:
球分别为100和110分。当速度现在彼此远离时,下一步中的碰撞处理将再次反转它们。所以位置靠得很近,速度每帧都在变化。球似乎“相互粘连”。
我希望答案可以帮助您理解您的问题。为了更好地实现弹性碰撞(仅处理每次碰撞一次),请查看此处:Ball to Ball Collision - Detection and Handling
答案 1 :(得分:0)
在我第一次尝试碰撞检测算法时偶然发现了类似的问题,我将尝试描述我认为这里的问题。
也许球的移动速度足够快,以至于在你的代码甚至检测到碰撞之前,它们已经部分地“相互”在一起。当碰撞检测到来时,它注意到它做了它应该做的事情:根据刚刚发生的碰撞的细节改变对象的计划轨迹。问题在于,因为在碰撞检测捕获它们之前这些对象被“合并”了,所以它们无法解开,因为碰撞检测再次被触发,相互捕获它们。
如果这是问题的根源,那么可能上面的代码可以使用足够小的速度矢量。当然,这不是一个真正的解决方案,但如果它确实适用于非常小的速度,它可能证实了我的假设,你对如何继续有了一些想法。