0

我有一个程序可以检查距离以及玩家是否与障碍物发生碰撞。我现在正在尝试计算障碍数组中的哪个障碍最接近移动的玩家,然后返回该障碍的索引。

这是我到目前为止所拥有的:

    public static int closestBarrier(GameObject object, GameObject[] barriers)
// TODO stub
{
    int closest = 0;

    for (int i = 0; i < barriers.length - 1; i++) {

        if (Math.sqrt((object.getX() - barriers[i].getX())
                * (object.getX() - barriers[i].getX()))
                + ((object.getY() - barriers[i].getY()) * (object.getY() - barriers[i]
                        .getY())) <= Math
                .sqrt((object.getX() - barriers[i + 1].getX())
                        * (object.getX() - barriers[i + 1].getX()))
                + ((object.getY() - barriers[i + 1].getY()) * (object
                        .getY() - barriers[i + 1].getY()))) {

            closest = i;
        } else
            closest = i + 1;

    }

    return closest;
}

我对 java 还是很陌生,所以我知道我已经拥有的可能不是很有效或最好的方法(甚至完全正确!?)。

4

1 回答 1

1

我会像这样重构它更简单一点:

public static int closestBarrier(GameObject object, GameObject[] barriers)
    {
        int closest = -1;
        float minDistSq = Float.MAX_VALUE;//ridiculously large value to start
        for (int i = 0; i < barriers.length - 1; i++) {
            GameObject curr = barriers[i];//current
            float dx = (object.getX()-curr.getX()); 
            float dy = (object.getY()-curr.getY()); 
            float distSq = dx*dx+dy*dy;//use the squared distance
            if(distSq < minDistSq) {//find the smallest and remember the id
                minDistSq = distSq;
                closest = i;
            }
        }

        return closest;
    }

这样您就可以减少距离检查(您的版本每次迭代进行两次距离检查)并且您只需要 id,而不是实际距离,因此您可以通过不使用Math.sqrt()并简单地使用平方距离来获得一点速度.

我能想到的另一个想法取决于布局。假设您有一个自上而下的垂直滚动条,您首先要检查障碍物的 y 属性。如果您有它们的散列或排序列表,对于屏幕底部的对象,您将开始从最大的 y 障碍到最小的循环。在 Y 轴上找到最近的障碍后,如果超过 1 个,您可以在 x 轴上检查最近的障碍。您不需要使用平方或平方根,因为您基本上将检查从每个障碍的 2D 中的 1 个检查拆分为 1D 中的 2 个检查,缩小障碍并丢弃远处的障碍,而不是一直检查每个对象.

更高级的版本将使用空间分区,但希望您在学习时不需要它来进行简单的游戏。

于 2013-03-25T13:47:03.783 回答