1

タイル マップを使用するプラットフォーマー ゲームに取り組んでいますが、これが良いアイデアかどうかはわかりません。

スポーンポイントなどを設定するためのツールを備えたきちんとしたタイルマップエディターを作成しましたが、マップを編集した後にゲームをテストプレイできるようにしたいので、将来の使用のためにもちろん、私が行った物理学を統合する必要がありますLibGDXに付属のBox2D!

タイルが衝突可能かどうかのデータを持つタイル マップから衝突マップを作成するメソッドを作成しています。

だから私はこの素晴らしいアイデアを思いつきました:

マップをループし、衝突しているタイルが見つかった場合は、隣接するタイルをループして、それらも衝突しているかどうかを確認します。衝突している四角形の幅と高さを設定するときに、衝突していないタイルが見つかるまでこれを行います

長方形の束を取得した後、それらを最大の正方形から最小の順に並べ替えて、最大のピースを取得し、長方形を最終リストに追加し、それらのいずれかが現在のボディと重なっている場合は最終的な長方形をチェックして、重なりがないようにします体

でもご存知のように、コードは 1000 以上の単語を伝えますよね?

    public void createBody() {
    List<Rectangle> allRects = new ArrayList<Rectangle>();
    for(int x = 0; x < info.getWidth(); x++) {
        for(int y = 0; y < info.getHeight(); y++) {
            if(tiles[x][y].getInfo().isColliding()) {
                int width = 1;
                int height = 1;

                //loop through neighbors horizontally
                for(int i = 0; i < info.getWidth() - x; i++) {
                    if(!tiles[x + i][y].getInfo().isColliding()) {
                        //if tile is not clipped, we set width to i which is current x offset


                        width = i;
                        break;
                    }
                }


                //only if width is bigger than zero can the rect have any tiels..
                if(width > 0) {
                    boolean breakingBad = false;
                    //loop through neighbors horizontally
                    for(int j = 0; j < info.getHeight() - y; j++) {
                        //loop though neigbors vertizally
                        for(int i = 0; i < width; i++) {
                            //check if tile is not colliding 
                            if(!tiles[x + i][y + j].getInfo().isColliding()) {
                                //and if so, we set height to j which is current y offset
                                height = j;

                                //breaking bad aka leaving both loops
                                breakingBad = true;
                                break;
                            }
                        }
                        if(breakingBad) {
                            break;
                        }
                    }
                }
                if(width * height > 0)
                    allRects.add(new Rectangle(x, y, width, height));
            }
        }
    }

    Collections.sort(allRects, new Comparator<Rectangle>() {

        @Override
        public int compare(Rectangle o1, Rectangle o2) {
            Integer o1Square = o1.width * o1.height;
            Integer o2Square = o2.width * o2.height;
            return o2Square.compareTo(o1Square);
        }
    });

    List<Rectangle> finalRects = new ArrayList<Rectangle>();
    mainloop:
    for(Rectangle rect: allRects) {
        for(Rectangle finalRect: finalRects) {
            if(finalRect.contains(rect)) {
                continue mainloop;
            }
        }
        finalRects.add(rect);
    }

    for(Rectangle rect: finalRects) {
        PolygonShape polyShape = new PolygonShape();
        polyShape.setAsBox((float)rect.getWidth() / 2, (float)rect.getHeight() / 2, Vector2.tmp.set((float)rect.getCenterX(), (float)rect.getCenterY()), 0f);

        mapBody.createFixture(polyShape, 1);
        polyShape.dispose();
    }

}

非効率的な?

ただし、この敷居はかなり非効率的です。これは、いくつかの理由で、たとえば右上隅など、可能なよりも小さなフィクスチャを作成しているためです。

また、中央の長方形の角に単一のフィクスチャを作成していますが、その理由がわかりません!

アイデア全体はすべて非効率的ですか?他の方法を使用するか、衝突マップを手動で作成する必要がありますか?それとも何が最善のアイデアでしょうか?

当初、各タイルは独自のフィクスチャであり、予想どおりエッジに奇妙なバグが発生しました

4

1 に答える 1

3

まず、カスタム タイル マッピング ツールは表面的には優れたアイデアですが、車輪を再発明することになります。

libGDX には、TMX マップのサポートが組み込まれています。 http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/maps/tiled/TmxMapLoader.html

自作エディターを使用する代わりに、この Tiled - http://www.mapeditor.org/などのフル機能のエディターを使用できます。

そのため、マップ用により優れたシステムが整ったら、オブジェクト指向の観点からこれを検討します。box2d の物理演算を使用するため、各collidableTile には body があります。したがって、必要なことは、各衝突可能タイルに物理ボディを割り当て、標準のタイル サイズに従ってサイズを設定することだけです。

box2d の世界とゲーム画面には違いがあることを忘れないでください。box2d はメートル単位で測定され、画面はピクセルで測定されます。したがって、位置とサイズを適切に設定するには、いくつかの計算を行う必要があります。一連のタイルで本体を共有する場合は、各 collidableTile を構築するときに本体をパラメーターとして渡し、検出できる隣接するタイルの数に基づいて本体のサイズを調整することができます。物理体のより複雑な形状は、より複雑になる場合があります。

これらのタイルを「スリープ」に設定することで、リソースを節約することもできます。この場合、box2d は、衝突が検出されるまで、これらのボディに対して削減されたシミュレーションを実行します。地形での衝突検出に box2d のみを使用している場合は、形状ライブラリを使用して交差を検出し、プレイヤー キャラクターのボディに box2d 物理を設定して、接触中に下向きの加速を停止するなど、他のオプションを検討することをお勧めします。なにか。

于 2013-07-15T20:22:37.730 に答える