我编写了一个相当简单的Java应用程序,它允许您拖动鼠标,并根据鼠标拖动的长度,它将沿该方向射击球,并随其弹起墙壁。
这是一个快速截图:
alt text http://img222.imageshack.us/img222/3179/ballbouncemf9.png
屏幕上的每个圆圈都是一个Ball对象。球的运动分解为x和y向量;
public class Ball {
public int xPos;
public int yPos;
public int xVector;
public int yVector;
public Ball(int xPos, int yPos, int xVector, int yVector) {
this.xPos = xPos;
this.yPos = yPos;
this.xVector = xVector;
this.yVector = yVector;
}
public void step()
{
posX += xVector;
posY += yVector;
checkCollisions();
}
public void checkCollisions()
{
// Check if we have collided with a wall
// If we have, take the negative of the appropriate vector
// Depending on which wall you hit
}
public void draw()
{
// draw our circle at it's position
}
}
这很好。所有的球都从一壁到另一壁反弹。
但是,我决定要包含重力的影响。我知道物体以9.8m / s的速度向地球加速,但是我不直接知道这应该如何转换为代码。我意识到yVector会受到影响,但是我对此进行的实验没有达到我想要的效果。
理想情况下,我希望能够在此程序中添加一些重力效果,并允许球反弹几次,然后再稳定到“地面”。
如何创建弹跳弹性重力效应?如何在每一步上操纵球的速度矢量?当它到达“地面”时必须做什么,以便我可以让它再次弹起,但比上一次短一些?
为我指出正确的方向提供了任何帮助。
谢谢大家的评论!它已经很好用了!
在step()中,我像人们建议的那样向我的yVector添加了一个重力常数,这就是我的checkCollision():
public void checkCollision()
{
if (posX - radius < 0) // Left Wall?
{
posX = radius; // Place ball against edge
xVector = -(xVector * friction);
}
else if (posX + radius > rightBound) // Right Wall?
{
posX = rightBound - radius; // Place ball against edge
xVector = -(xVector * friction);
}
// Same for posY and yVector here.
}
但是,这些球将继续在地板上滑动/滚动。我认为这是因为每次反弹时我只是取其向量的一个百分比(90%),而它永远不会真正为零。我应该添加一个检查,如果xVector变为某个绝对值,我应该将其更改为零?
最佳答案
您要做的就是不断从yVector中减去一个小的常数(代表9.8 m / s的常数)。当球下降时(yVector已经为负),这会使球走得更快。当它上升时(yVector为正)它将减慢它的速度。
这不会解决摩擦,因此事物应该永远反弹。
编辑1:
为了解决摩擦,只要它反转(并且您使符号反转),就应稍微降低绝对值。就像它到达yVector = -500一样,当您反转符号时,使其变为+480而不是+500。您可能应该对xVector做同样的事情,以防止它左右跳动。
编辑2:
另外,如果您希望它对“空气摩擦”做出反应,则每次调整时都应将这两个向量减小很小的量。
编辑3:
关于永远在底部滚动的问题-根据数字的高低,这可能是两件事之一。要么您的数字很大,似乎需要永远地完成它,要么您是四舍五入,并且您的向量始终为5左右。 (5的90%是4.5,因此可能会四舍五入到5)。
我将打印出一条调试语句,然后查看Vector的编号。如果它们到达5左右的位置并停留在那里,则可以使用将分数截断为4而不是舍入为5的函数。如果它继续下降并最终停止,则可能必须提高摩擦系数。
如果找不到简单的“四舍五入”函数,则可以使用(0.9 * Vector)-1,从现有方程式中减去1应该做同样的事情。