【问题标题】:How should I alter my collision detection for a rotating line?我应该如何更改旋转线的碰撞检测?
【发布时间】:2013-02-14 15:59:33
【问题描述】:

我为我的“线”创建了一个矩形,它是一个旋转的“激光瞄准器”

public Rectangle getLaserBox() {
    float lOriginX = (leon.getPosition().x + 0.27f);
    float lOriginY = (leon.getPosition().y + 0.7f);
    float lEndX = lOriginX + (float)Math.cos((leonAimLaserSprite.getRotation())/57) * 5f;
    float lEndY = lOriginY + (float)Math.sin((leonAimLaserSprite.getRotation())/57) * 5f;
    Rectangle laserBox = new Rectangle(lOriginX, lOriginY, lEndX, lEndY);
    return laserBox;
}

然后我有一个检查矩形重叠的方法,如果检测到重叠,应该缩短“激光瞄准器”精灵。我现在在我的渲染方法中调用laserCol() 方法(我知道我正在破坏MVC,只是想让它工作),我的laserWidth 被应用为激光精灵的宽度。

private float laserWidth;

public void laserCol() {
    Vector2 laserOrigin = new Vector2(leon.getPosition().x + 0.55f, leon.getPosition().y + 0.7f);
    boolean laserIsCol = false;
    for (Tile t : world.getTiles()) {     //pulling in tiles as t, from world method getTiles()
        laserWidth = laserOrigin.dst(t.getPosition().x + 0.1f, t.getPosition().y + 0.7f);
        if (Intersector.overlapRectangles(getLaserBox(), t.getBounds())) {
            laserIsCol = true;
        }
    }
    if (laserIsCol) {
        for (Tile t : world.getTiles()) {     //pulling in tiles as t, from world method getTiles()
            laserWidth = laserOrigin.dst(t.getPosition().x, t.getPosition().y + t.getBounds().y);
        }
    }
    if (!laserIsCol) {
        laserWidth = 8f;
    }
}

但正如您在屏幕截图中看到的那样,激光并没有缩短。我查看了其他示例,但似乎无法理解更好的方法来做到这一点。

所以在添加了我在代码中调用的单个对象之后,我决定检查我创建的精灵边界框,它看起来像这样。

在那之后,我更改了一些代码,并尝试使用射线,我已经让它工作了一些,但它不像我想要的那样接近,有什么建议吗?

public Ray getLaserRay() {
    lOriginX = (leon.getPosition().x + 0.27f);
    lOriginY = (leon.getPosition().y + 0.7f);
    lEndX = lOriginX + (float)Math.cos((leonAimLaserSprite.getRotation())/57) * 10f;
    lEndY = lOriginY + (float)Math.sin((leonAimLaserSprite.getRotation())/57) * 10f;
    laserO = new Vector3(lOriginX, lOriginY, 0);
    laserD = new Vector3(lEndX, lEndY, 0);
    Ray laserRay = new Ray(laserO, laserD);
    return laserRay;
}


private float laserWidth;

public void laserCol() {
    Vector2 laserOrigin = new Vector2(leon.getPosition().x + 0.55f, leon.getPosition().y + 0.7f);
    boolean laserIsCol = false;
        if (Intersector.intersectRayBoundsFast(getLaserRay(), thing.getBB())) {
            laserIsCol = true;
        }
    if (laserIsCol) {
            laserWidth = laserOrigin.dst(thing.getPosition().x, thing.getPosition().y);
        }
    if (!laserIsCol) {
        laserWidth = 10f;
    }
}

我最终使用了 2 个线段来使碰撞检测起作用。我为激光瞄准器做了一个,为我的对象(敌人)做了一个,从较低的 x 点延伸到顶部的 x 点。除了我使用了 libgdx 中的段相交之外,基本上是相同的代码。

有人知道如何在激光瞄准点上造成子弹或损坏吗?

【问题讨论】:

  • 在没有更多代码的情况下很难诊断问题。你用调试器单步调试了吗?

标签: java collision-detection libgdx


【解决方案1】:

没有更多信息我只能猜测,但我认为问题可能是您正在使用列表/数组中的所有图块计算宽度。相反,您应该只使用激光碰撞的瓷砖来计算宽度。

类似这样的:

laserWidth = 8f; //default if no collision is found
for (Tile t : world.getTiles()) {     //pulling in tiles as t, from world method getTiles()
    if (Intersector.overlapRectangles(getLaserBox(), t.getBounds())) {
        laserWidth = laserOrigin.dst(t.getPosition().x, t.getPosition().y + t.getBounds().y);
        break;
    }
}

请注意,我只是重用了您的代码,我不知道这是否正确,或者其中是否有一些错误的计算。正如我在评论中所说,您应该调试计算并查看它们开始出错的地方。

【讨论】:

  • 我使用了一些调试器,但通常只是寻找空对象,不确定如何正确查看计算结果。我将创建一个类似瓷砖的东西,但只是一个对象并用它来检查它。另外,你用这段代码做了什么改变?休息是什么?做什么?
  • break 结束循环。但这可能不正确,因为我不知道您的其他代码是做什么的。检查所有图块并使用最短宽度可能会更好,这应该是最近命中的结果。至于调试计算:您逐步通过调试器并检查每个步骤的值是否仍然有意义。不过,您可能需要手动进行一些粗略的计算,以便了解它们是否有意义。
猜你喜欢
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多