0

こんにちは、Ryan と申します。現在、独自の 2D Java ゲームを開発しています。現在、ゲームの世界には多くのオブジェクトがあります。ゲームを新たに開始すると、配列リストとツリー クラスを使用して作成された、ランダムに配置された 100 個の房がワールドに読み込まれます。私のゲームでは、呼び出されたクラスを使用してcheckcollisions、プレーヤーが房と交差しているかどうかを確認します。次に、このメソッドをメソッド内に配置しますupdate。このメソッドが呼び出されていない場合、余分な 100 FPS が得られます。まだこの 100 fps を取得できますが、衝突をチェックできますか? ゲームが現在 30 ~ 50 fps で実行されているため、FPS ブーストが本当に必要です

ここにcheckcollisionsコードがあります:

public void checkCollisions() {
    for (int i = 0; i < Placing_Objects.Small_Trees.size(); i++) {
        if (player.getBounds().intersects(Placing_Objects.getSmall_Tree().get(i).getBounds())) {
            if (gotAxeOn) {Placing_Objects.Small_Trees.get(i).health -= rand.nextInt(3);}
        }
        if (Placing_Objects.Small_Trees.get(i).health <= 0) {
            Placing_Objects.removeSmall_Tree(Placing_Objects.Small_Trees.get(i));
            Inventory.addItemToInv("Wood");
            Inventory.addItemToInv("Wood");
            Inventory.addItemToInv("Stick");
            Player.exp += rand.nextInt(3);
            challenges.choppedDownTrees += 1;
        }
    }
}
4

5 に答える 5

3

プレイヤーの近くにある木、または現在表示されている長方形内にある木との衝突のみをチェックします。これを効率的に行うには、表示されているオブジェクトの配列を保持し、それらに対してのみ反復します。

于 2013-10-30T17:06:55.257 に答える
2

Wilbert が述べたように、kd-tree は完璧なソリューションです。動かないオブジェクトがたくさんある単純な 2D ゲームの場合は、より単純なアプローチを試すことができます。

まず、すでに行っているようにすべてのツリーをセットアップします。

ここに画像の説明を入力

これらすべてのツリーを ArrayList に保持します。

ゲーム フィールドを同じサイズの x 長方形 (たとえば 3x5=15) に分割し、どのツリーがどの領域と交差するかを確認します。これらの計算を適切なデータ構造に保存します。例えば:

HashMap<Rectangle, ArrayList<Tree>> fieldSperation;

ここに画像の説明を入力

木の中にある白い数字は、それらが交差する Rectangle を示します。1 つのツリーが複数の Rectangle と交差する可能性があります。次に、2 つ以上のリストで参照を保持する必要があります (例 6/7 または 7/12)。

最後に、次のように checkCollisions() メソッドを調整できます。

public void checkCollisions() {
    // 1. check which Rectangle intersects with the player (can be a maximum of 4)
    for (Rectangle r : fieldSeperation.keySet()) {
         if (playerRect.intersect(r)) {
             // 2. do your collision detection with those trees which are intersecting with those
             // trees which are intersecting with the rectangles from 1.)
             for (List<Tree> ts : fieldSeperation.get(r)) {
                 // your old code here
             }
         }
     }
}

このテクニックは、パフォーマンス要件を満たすのに十分であると確信しています。

于 2013-10-30T17:47:17.220 に答える
1

衝突テストに空間データ構造を使用します。このような構造を使用すると、テストの数を大幅に減らすことができます。

2D の 2 つのシンプルで効率的な構造は、quadtreeまたはkd-treeです。

Java での kd-tree 実装へのリンクを含む関連する質問は、こちらにあります

于 2013-10-30T17:08:47.533 に答える
0

コードを再配置したところ、正常に動作するようになりました! この質問を何度も投稿して申し訳ありません...私はこれが初めてで、自分が何をしているのか本当に知りませんでした。困っている開発者を助けてくれたすべての人にもう一度感謝します! 新しいコードは次のとおりです。

for (int i = 0; i < Placing_Objects.Small_Trees.size(); i++) {
        if (gotAxeOn) {
            if (player.getBounds().intersects(Placing_Objects.getSmall_Tree().get(i).getBounds())) {
                Placing_Objects.Small_Trees.get(i).health -= rand.nextInt(3);
                }
        }
        if (Placing_Objects.Small_Trees.get(i).health <= 0) {
            Placing_Objects.removeSmall_Tree(Placing_Objects.Small_Trees.get(i));
            Inventory.addItemToInv("Wood");
            Inventory.addItemToInv("Wood");
            Inventory.addItemToInv("Stick");
            Player.exp += rand.nextInt(3);
            challenges.choppedDownTrees += 1;
        }
    }
于 2013-10-31T15:50:02.813 に答える
0

Swing イベント ディスパッチ スレッドで衝突をチェックしません。それを実行する並行スレッドを作成すると、イベント スレッドは単にそれらをそれに割り当てます。画面上にある木のみを最大にチェックして、チェックされる衝突の量を減らします。

于 2013-10-30T17:33:23.713 に答える