【问题标题】:How to detect which side has been hit of a Rectangle in Java如何检测Java中矩形的哪一侧被击中
【发布时间】:2015-12-03 21:38:54
【问题描述】:

我正在用 Java 制作一个 Breakout 游戏,我已经到了需要能够检测砖的哪一侧被球相交的地步。目前我正在使用 intersects 方法,但是这只检测交叉点,而不是具体的哪一侧被击中。方法是这样的(我在一些cmets里加了):

public boolean intersects(Rectangle r) {
    // The width of the Brick as tw
    int tw = this.width;
    // The height of the Brick as th
    int th = this.height;
    // The width of the given Rectangle as rw
    int rw = r.width;
    // The height of the given Rectangle as rh
    int rh = r.height;
    // Check if the given Rectangle or Brick does not exist
    if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {

        // If not, then return false because there is nothing to collide/intersect
        return false;
    }

    // The x location of Brick as tx
    int tx = this.brickLocation.x;
    // The y location of Brick as ty
    int ty = this.brickLocation.y;
    // The x location of the given Rectangle as rx
    int rx = r.x;
    // The y location of the given Rectangle as ry
    int ry = r.y;

    // RW = RW + RX
    rw += rx;
    // RH = RH + RY
    rh += ry;
    // TW = TW + TX
    tw += tx;
    // TH = TH + TY
    th += ty;

    //      overflow || intersect
    return ((rw < rx || rw > tx) &&
            (rh < ry || rh > ty) &&
            (tw < tx || tw > rx) &&
            (th < ty || th > ry));
}

我现在已经将此方法放入我的一个类中并且我正在对其进行自定义,但是我在制作它时遇到了麻烦,以便它检测到哪一侧被击中,因为最终的 return 语句是如此相互关联,你可以'不要只取其中一条线,因为为了让它知道那一边的终点,它需要知道另一边,这就是它在这里所做的,如果它与所有边相交(并且没有限制双方的外展——虽然显然它们是有限的)然后它返回真,如果不是那么不是并且它没有触及形状,否则它会这样做。

我想做的就是让它有 if 语句来决定返回什么 int(我会将它的返回类型从 boolean 更改为 int),因此它击中了哪一侧它可以以适当的方式反弹。但是因为它们是如此相互依赖,我不知道如何将它们分开:

    //      overflow || intersect
    return ((rw < rx || rw > tx) &&
            (rh < ry || rh > ty) &&
            (tw < tx || tw > rx) &&
            (th < ty || th > ry));

我在这里看到了许多类似的问题,但是它们使用不同的语言,没有任何答案,或者没有任何答案可以回答问题并已被接受。所以我想知道是否有人可以向我建议我如何将它们分开,以便它可以检测到哪一方被击中,因为我没有想法?
或者,也许已经有一种 Java 方法可以为我做到这一点,而我不必覆盖已经存在的方法?我有最新版本的 Oracle JDK 8。

【问题讨论】:

  • 我认为你应该画一个图表并标记哪些坐标是什么;这应该可以帮助您了解“相互关联”的声明到底是什么。哦,其他答案用什么语言写的并不重要 - 数学永远是数学。
  • 如果你通过在它的坐标上添加偏移来“移动”球,使用更大的偏移来获得更高的速度,你必须准备好在任何时间范围内不与边缘相交。更糟糕的是,你可以用非常快的球运动与对边相交。计算边缘交叉点在这里是错误的方法。

标签: java java-8 collision-detection game-physics rectangles


【解决方案1】:

您可以这样做的一种方法是在移动球时,我假设您会这样做:

ball.x += speedX;
ball.y += speedY;

你可以把它变成这样:

ball.x += speedX;
if (intersects(ball, brick))
{
    //Ball touched brick on left/right side (depending if speedX is positive or negative)
}
ball.y += speedY;
if (intersects(ball, brick))
{
    //Ball touched brick on top/bottom side (depending if speedY is positive or negative)
}

【讨论】:

  • 如果你走这条路,你可以让intersects 接受另一个参数,指示检查左/右或上/下。这样您就不会在两个部分中都进行检查。
  • @gonzo 虽然我同意,但有一些方法可以避免两次调用intersects(),你的方式听起来不对。如果它只检查左/右,在第一次调用中,它可能会在球在砖块上方时返回真。只要它有效,它就是 OP 的应用程序,可以根据他们的需要对其进行优化。
【解决方案2】:

尝试让你的 intersects(Rectangle r) 函数在没有碰到任何边的情况下返回 -1,并让 0-1-2-3 来确定你碰到的边。根据增加的部分..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多