【问题标题】:Java: Checking rectangle collision against multiple objectsJava:检查多个对象的矩形碰撞
【发布时间】:2017-02-09 08:37:04
【问题描述】:

我一直在通过尝试一个小“游戏”来学习 Java,该“游戏”从尝试跳球开始。我有 3 个课程(JumpingBall3、BallSprite3 和 Floor),并且已经实现了某种重力、始终如一的跳跃以及对地板的检测以阻止球无限下落。最后一点,我发现了未来发展的潜在问题。现在我有两个由 JumpingBall3(“floor1”和“platform”)创建的楼层,我使用以下代码检测 BallSite3 内的碰撞:

public boolean collision() 
{

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

    return onFloor;
}

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

我已经在网上发布了完整的代码here,在这篇文章中包含似乎有点冗长。

【问题讨论】:

    标签: java collision-detection collision


    【解决方案1】:

    最简单的做法是将所有要检查的对象保存在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);
    }
    

    【讨论】:

    • 有趣,谢谢!我将对集合和列表进行一些阅读,因为它们听起来与我想要实现的目标和我目前的知识水平完全一样。还要感谢这个小例子,这真的有助于证明你在解释什么。我还将研究 Stream API。
    【解决方案2】:

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

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

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

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

    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);
        }
    }
    

    【讨论】:

    • 感谢您的回答!这绝对看起来像是我将来会提到的东西。虽然这对我来说似乎有点先进,但随着我继续开发这个项目的复杂性,实体、常见行为和处理碰撞行为的多种方法的概念似乎是我即将遇到的事情。 :)
    • @Jonathan 没问题。制作类似应用程序的游戏是一件困难的事情,因为有很多状态、时间问题和空间问题。最好的方法是为所有事物制作完全理解的小型构建块,然后慢慢将它们组合在一起。
    【解决方案3】:

    创建一个包含所有对象的列表。然后对所有要检测的对象使用循环(当然检测的对象除外)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-08
      • 2015-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多