Java: 检查矩形与多个对象的碰撞

Java: Checking rectangle collision against multiple objects

我一直在通过尝试一些 "game" 来学习 Java,开始时只是尝试让球跳起来。我有 3 个 classes(JumpingBall3、BallSprite3 和 Floor),并实现了某种重力、持续有效的跳跃以及对地板的撞击检测以阻止球无限下落。通过最后一点,我发现了未来发展的一个潜在问题。现在我有两个由 JumpingBall3 ("floor1" & "platform") 创建的楼层,我使用以下代码检测 BallSpite3 内的碰撞:

public boolean collision() 
{

    if (game.floor1.getBounds().intersects(getBounds()) || game.platform.getBounds().intersects(getBounds()))        {
        onFloor = true;
    }
    else 
    {
        onFloor = false;
    }

    return onFloor;
}

如果我继续添加更多楼层或平台,"if" 条件在长度方面很快就会失控。有没有办法创建一个循环遍历在我的 JumpingBall3 class 中创建的所有可见 Floor 对象的方法?

我已经 post 在线编辑了完整的代码 here,在 post.

中包含它似乎有点冗长

创建包含所有对象的列表。然后在你想要检测的所有对象上使用一个循环(当然除了进行检测的对象)

最简单的做法是将所有要检查的对象保存在 Collection 中,例如 List,然后遍历此 List.

因此,例如,这里一个不错的选择是使用 Floor 的集合,我们对其进行迭代以检查是否与其中一个发生碰撞。

public boolean collision() {
    boolean onFloor = false;
    Rectangle rectangle = getBounds();
    for (Floor floor : floors) {
        if (floor.getBounds().intersects(rectangle)) {
            onFloor = true;
            break;
        }
    }
    return onFloor;
}

假设您使用 Java 8 ,您可以依靠 Stream API 来做与下一个相同的事情:

public boolean collision() {
    Rectangle rectangle = getBounds();
    return floors.stream().map(Floor::getBounds).anyMatch(rectangle::intersects);
}

这个问题的一个可行的解决方案是让你的 "game world" 包含一个实体列表(其中一个实体可以是球或墙或游戏对象中的任何其他对象),并有一些机制来检测哪个实体靠近其他实体。这最终会调用某种类型的 entity.checkCollision(neighborEntity) 方法。

你仍然需要有不同的行为来与不同的实体发生碰撞。您可以通过让基础 Entity class 具有一些可以关闭或打开的公共属性,或者存储可以直接应用于碰撞实体的行为来实现。

// within some game loop, check for collisions
for (Entity entity : collidableEntities)
{
    ball.checkCollision(entity);
}

您的 classes 可能看起来像这样具有编程行为。

public Entity
{
    public void applyCollisionBehaviorTo(Ball ball) { // Override to do something}

    public void onCollision() { // Override to do something }

    public collidesWith(Entity neighbor) { // your collision math }

    public void checkCollision(Entity neighbor)
    {
        if (collidesWith(neighbor))
        {
            onCollision()
        }
    }
}

public Wall extends Entity
{
    @Overide
    public void applyCollisionBehaviorTo(Ball ball)
    {
        ball.reverseDirection();
    }
}

public Ball extends Entity
{
    @Overide
    public void onCollision(Entity collidingEntity)
    {
        collidingEntity.applyCollisionBehaviorTo(this);
    }
}