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