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

このようにすると、距離チェックが少なくなり(バージョンでは、反復ごとに2つの距離チェックが実行されます)、実際の距離ではなくIDのみが必要になるため、Math.sqrt()代わりに距離の2乗を使用せずに使用することで、速度を少し上げることができます。 。

私が考えることができる別のアイデアは、レイアウトによって異なります。トップダウンの垂直スクローラーがあるとすると、障害物のyプロパティを確認することから始めます。それらのハッシュまたはソートされたリストがある場合、画面の下部にあるオブジェクトの場合、最大のyバリアから最小のyバリアへとループを開始します。Y軸上で最も近いバリアを見つけたら、1つ以上ある場合は、x軸上で最も近いバリアを確認できます。基本的に、チェックをバリアごとに2Dの1つから1Dの2つのチェックに分割し、すべてのオブジェクトを常にチェックするのではなく、バリアを絞り込んで遠くのバリアを破棄するため、平方根または平方根を使用する必要はありません。。

さらに高度なバージョンではスペースパーティションを使用しますが、学習中の単純なゲームではスペースパーティションが必要ないことを願っています。

于 2013-03-25T13:47:03.783 に答える