1

私はゲームのランダム化に歯を食いしばっており、Binding Of IsaccやSperlunkyのようなゲームが、機能的なフロア/レベルを作成するためにランダムに配置されたプレハブレベルのフラグメントを使用するトリックを理解しようとしています。

フロアには常にプレーヤー、出口、ボーナスルーム(黄色の点)が含まれます。接続されている部屋は互いに直接接続されています。

私はそれをどうやって進めるかについてかすかな考えを持っています:タイルマップとグリッドデータを保持する多次元配列を作成することから始めます:

public static var levelLayout:Array =
[[tile,grid],[tile,grid],[tile,grid],[tile,grid]
[tile, grid],[tile,grid],[tile,grid],[tile,grid] etc]

そして、そこから、各グリッドスペースを調べ、そのスポットが何もないかどうかを確認します。また、部屋が孤立している場合は部屋を何も作成せず、すべてのタイルマップ/グリッドを含むシャッフルされた配列から部屋の割り当てを開始します。

私は正しい方向に進んでいますか?出口をどのように処理する必要がありますか?どんな助けでもいただければ幸いです。乾杯

4

2 に答える 2

0

Spelunky や Rogue Legacy に触発されて、私自身も最近このような情報を調べています。いろいろ読んでいると、Spelunky のレベル レイアウトがどのように生成されるかについて、 http: //tinysubversions.com/spelunkyGen/ に多くの情報があることがわかりました。

これに触発されて(盗まれた?)、これの単純なバージョンを装備して、単一のソリューションパスを持つ多次元配列を生成し、0〜5の数字を使用して各セルが表す部屋のタイプを識別しました(リストされたサイトに基づいて)その上)。必要に応じて、異なるタイプの結果を簡単に返すことができることに注意してください。また、全体で Math.random() を使用しましたが、必要に応じて FP.rand() に置き換えることもできます。任意のサイズの部屋 x 部屋のレベル レイアウトをサポートします。デフォルトは 4 x 4 です。いくつかのランダムな結果 [より読みやすくするために編集]:

4 x 4         6 x 5               7 x 12
[S][ ][ ][ ]  [ ][ ][ ][ ][ ][S]  [v][-][-][-][-][-][S]
[v][ ][ ][ ]  [ ][ ][v][-][-][^]  [^][-][-][-][-][-][v]
[^][-][-][v]  [ ][v][^][ ][ ][ ]  [ ][ ][v][-][-][-][^]
[E][-][-][^]  [v][^][ ][ ][ ][ ]  [v][-][^][ ][ ][ ][ ]
              [^][-][-][-][-][E]  [v][ ][ ][ ][ ][ ][ ]
                                  [^][-][-][-][-][-][v]
                                  [ ][ ][v][-][-][-][^]
                                  [v][-][^][ ][ ][ ][ ]
                                  [v][ ][ ][ ][ ][ ][ ]
                                  [^][-][-][-][-][-][v]
                                  [ ][ ][ ][ ][ ][ ][v]
                                  [E][-][-][-][-][-][^]

いずれにせよ、Spelunky の 4x4 レイアウトにより適していると思います (なぜだろうと思います)。少しずれていることは確かですが、私のコードは次のとおりです。

/**Generates a pseudo-random single solution path layout to be used for tile painting
 * @param   dimenR Number of rows (Y-Axis) Should correspond with height of level, in rooms
 * @param   dimenC Number of columns (X-Axis) Should correspond with width of level, in rooms
 * @return  The resulting multi-dimensional array*/
private function generateNewRoomLayout(dimenC:int = 4, dimenR:int = 4):Array {
    // NOTE: 0= non solution, 1= left/right, 2= left/right/down, 3= left/right/up, 4= start, 5= end
    // Initialize array as all non-solution path rooms
    var generatedLayout:Array = new Array(dimenR);
    for (var i:int = 0; i < dimenR; i++) {
        generatedLayout[i] = new Array(dimenC);
        for (var j:int = 0; j < dimenC; j++) { generatedLayout[i][j] = 0; }
    }
    // Initialize our Start Room location
    /**Position along X-Axis in the grid*/
    var column:int = Math.random() * dimenC;
    /**Position along Y-Axis in the grid*/
    var row:int = 0;
    generatedLayout[row][column] = 4;
    /**Chooses the next direction. 0-1= left, 2-3= right, 5= down*/
    var chooseDirection:int = Math.random() * 6;
    /**Direction solution path is currently taking. -1= left, 1= right*/
    var currentDirection:int = 0;
    // Keep running until our position goes beyond the dimension of the grid
    while (row < dimenR) {
        // Chosen to go downards
        if (chooseDirection == 5) {
            // Reset which way we're going so we can make a random choice later
            currentDirection = 0;
            if (generatedLayout[row][column] != 4) { generatedLayout[row][column] = 2; }
            // Bottom row
            if (row == dimenR - 1) {
                generatedLayout[row][column] = 5; // Found our ending point
                break;
            }
            else {
                row++;
                generatedLayout[row][column] = 3;
            }
        }
        else {
            // If we don't have a direction to go left/right
            if (currentDirection == 0) {
                if (chooseDirection < 3) { currentDirection = -1; }
                else { currentDirection = 1; }
            }
            // If we're at the edge of the grid and trying to move past it, we move down and flip our direction instead
            if ((currentDirection < 0 && column == 0) || (currentDirection > 0 && column == dimenC - 1)) {
                currentDirection = -currentDirection;
                generatedLayout[row][column] = 2;
                if (row == dimenR - 1) {
                    generatedLayout[row][column] = 5;
                    break;
                }
                else {
                    row++;
                    generatedLayout[row][column] = 3;
                }
            }
            else {
                column += currentDirection;
                generatedLayout[row][column] = 1;
            }
        }
        chooseDirection = Math.random() * 6;
    }
    return generatedLayout;
}
于 2014-07-20T22:47:44.620 に答える
0

完璧な迷路 (迷路内のどこからでも、迷路内の任意のポイントに到達できる迷路) を作成することから始めます。これは、勝てる/解決できる方法で接続された部屋のネットワークを作成するのに役立ちます。

これを行うためのチュートリアルはたくさんあります。これは少し汚れていて、必要のないコードがたくさんありますが、さまざまなアプローチを理解するために、これに関連するいくつかの例に目を通すことをお勧めします: http://www.emanueleferonato.com/2008/11/28/perfect -迷路生成 with-as3/

私は再帰的なバックトラッキング アルゴリズムで幸運に恵まれました: http://en.wikipedia.org/wiki/Maze_generation_algorithm#Recursive_backtracker

迷路の各セルを部屋と見なします。迷路が構築されると、どの部屋が他の部屋に接続されているかがわかるので、各部屋に次の部屋に接続するためのドアまたは壁を設ける手段を用意します。おそらく、4x4 の完全な迷路のようなものを作りたいと思うでしょう。

味付けの仕方~

迷路から行き止まりを安全に取り除くことができ、それでも完璧です。迷路が生成されたら、迷路内のすべてのセルをループします。壁が 3 つあるセルは行き止まりであり、完全に壁で仕切ることができます。または、秘密の部屋にするか、何でもします。

迷路にループを追加します。以前は接続されていなかった迷路内の 2 つの部屋をランダムに接続します。これでも迷路は完璧に保たれますが、少しオープンになります。

これは楽しい領域です、楽しんでください :)

于 2012-12-02T19:23:30.547 に答える