【问题标题】:Collision detection for circles圆的碰撞检测
【发布时间】:2015-06-01 03:02:23
【问题描述】:

我有一个简单的 Java 小程序,它有两个用户控制的球,使用 java.awt 绘制。我需要一种方法来检测它们之间的碰撞。我有一个检测与墙壁碰撞的算法:

if (xPosition > (300 - radius)){
   xSpeed = -xSpeed; 
}
else if (xPosition < radius){
   xSpeed = -xSpeed; 
}
else if (yPosition > (300 - radius)) {
   ySpeed = -ySpeed;
}
else if (yPosition < radius){
   ySpeed = -ySpeed;
}
xPosition += xSpeed;
yPosition += ySpeed;

第二个球:

if (xPosition2 > (300 - radius)){
   xSpeed2 = -xSpeed2; 
}
else if (xPosition2 < radius){
   xSpeed2 = -xSpeed2; 
}
else if (yPosition2 > (300 - radius)) {
   ySpeed2 = -ySpeed2;
}
else if (yPosition2 < radius){
   ySpeed2 = -ySpeed2;
}
xPosition2 += xSpeed2;
yPosition2 += ySpeed2;
  • 小程序为 300 x 300 像素。
  • radius 存储圆的半径。
  • xPositionxPosition2 存储两个球的 x 坐标。
  • yPositionyPosition 存储两个球的 y 坐标,
  • xSpeedxSpeed2 存储两个球的 x 速度。
  • ySpeedySpeed2 存储两个球的 y 速度。

【问题讨论】:

  • 欢迎来到 SO,鲍勃。这实际上更像是一个数学问题而不是一个编程问题,因为没有办法做你想要内置到 Java 语言中的东西。不过,为了让您开始,请这样想:检测碰撞意味着检测球何时会重叠或接触,对吧?你知道他们的位置和大小......
  • 是的,但我什么都想不出来。我试着通过数学来做,结果我得到了一个相互穿过的球和大约 30 行无用的代码

标签: java awt collision-detection


【解决方案1】:

使用http://java.sun.com/j2se/1.5.0/docs/api/java/awt/geom/Point2D.html,那里有一个距离方法,如果它小于它们碰撞的半径。

编辑: Err,小于半径 * 2 ,抱歉

【讨论】:

  • 酷谢谢!我听说过一个相交命令.. 但显然这只适用于矩形。
  • 为了纪念 Bob Twinkles,我 +1
  • 我只是看了一下,但是如何将位置传递给方法
  • 您将实例化 Point2d。我建议您使用此类存储位置。
  • int 起始XPosition =0; int 开始YPosition = 0; java.awt.Point position = new java.awt.Point(startingXPosition,startingYPosition);将点声明为字段并使用 position.getX() 和 position.getY()。碰撞测试: boolean isColliding = position.distance(anotherBall.getPosition())
【解决方案2】:

Java 中有 Point2D,或者你可以自己做,圆/圆碰撞或球体/球体碰撞非常容易。

int distXX = (xPosition1 - xPosition2) * (xPosition1 - xPosition2);
int distYY = (yPosition1 - yPosition2) * (yPosition1 - yPosition2);
if ( radius*radius > distXX * distYY ) {
   ...  // There's a collision
}

【讨论】:

  • 请注意,典型的游戏开发新手错误是开始使用“平方根”来计算距离并检查半径,而不是不求平方根并检查 radius x 半径。上面的解决方案只使用离散匹配,实际上在很多游戏中使用的(几十年前一直在写游戏,这是 the方法)。
  • 好的,我刚刚编译并运行,球与除另一个球外的所有物体发生碰撞
【解决方案3】:
 public boolean colliding(Ball anotherBall) {
    double xDelta = (this.x + this.ballSize/2 + this.dx) - (anotherBall.x + anotherBall.ballSize/2 + anotherBall.dx);
    double YDelta = (this.y + this.ballSize/2 + this.dy) - (anotherBall.y + anotherBall.ballSize/2 + anotherBall.dy);
    double distance = Math.sqrt(Math.pow(xDelta, 2) + Math.pow(YDelta, 2));

    return (distance <= this.ballSize/2 + anotherBall.ballSize/2);

}

【讨论】:

  • erm 这很好,但我正在运行一个类的整个应用程序
【解决方案4】:

这个链接非常有用!

Circle-Circle Collisions

很详细,很有教养


在该页面的底部还有另一个链接,指向更详细的内容!


我使用了中心之间的距离方法 --- Circles

通过测量每个中心之间的距离,您可以判断它们是否发生碰撞。 距离不应大于 2 半径之和。

这就是我所做的:

private boolean checkDrawContains(ShapeDrawable newHole) 
{
    long newCenterX = newHole.getBounds().left + (newHole.getBounds().width()/2); //Get the center of my shapes
    long newCenterY = newHole.getBounds().top + (newHole.getBounds().height()/2);

    for(ShapeDrawable hole: mHoles) // I was storing the circles in an ArrayList
    { 
        long centerX = hole.getBounds().left + (hole.getBounds().width()/2); //Get the center of my shapes
        long centerY = hole.getBounds().top + (hole.getBounds().height()/2);
        long x = centerX - newCenterX;
        long y = centerY - newCenterY;
        long aux = (long) ((Math.pow(Math.abs(x),2)) + (Math.pow(Math.abs(y),2))); //Pythagoras the hard way :P
        long distance = (long) Math.sqrt(aux);
        long sRads = (newHole.getBounds().width()/2) + (hole.getBounds().width()/2);

        if(distance <=  sRads ) {
            return true;  //Is Colliding!
        }
    }
    return false; // Is not Colliding!
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-02
    • 1970-01-01
    • 2010-10-16
    • 2016-08-08
    • 2013-01-28
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多