实际上,我最近一直在研究类似的信息,受到 Spelunky 和 Rogue Legacy 的启发。在阅读时,我发现有很多关于如何在http://tinysubversions.com/spelunkyGen/上生成 Spelunky 中的关卡布局的信息
受此启发(被盗?),我装配了一个简单版本,以生成具有单个解决方案路径的多维数组,使用数字 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;
}