试一试Tyrant地牢生成算法
程序员文章站
2022-07-13 08:35:06
...
话题
我看到一篇文章讲了一种 Roguelike 地牢生成算法:一种 Roguelike 地牢生成算法 | indienova 独立游戏。这篇文章是翻译,原作者是一款名叫“Tyrant”游戏的作者,在讲自己制作这款游戏时用的地牢生成算法。可我没找到这款游戏的发行版,源代码倒是有:Tyrant - Java Roguelike download | SourceForge.net。可惜是Java工程,而我不会Java。
虽然没有工程源代码,但是有单独算法的C#代码:CSharp Example of a Dungeon-Building Algorithm - RogueBasin。我想那我就试一试跑起来它,并用Unity显示出来结果吧
实践
代码跑起来并不困难,主要就是补上了一些枚举类和结构体的声明,并修改一些小细节,算法本身没有任何改动。完整的Unity工程见:完整Unity工程。
生成的一些结果如下:
生成的速度很快(虽然目前元素还比较少)
分析
算法思路概括起来就是:
选一个元素,尝试修建,如果成功了就继续,失败的话就再来。
我觉得关键点在于元素的设计。我研究了这段算法中这部分代码:
// choose what to build now at our newly found place, and at what direction
int feature = this.GetRand(0, 100);
if (feature <= ChanceRoom)
{ // a new room
if (this.MakeRoom(newx + xmod, newy + ymod, 8, 6, validTile.Value))
{
currentFeatures++; // add to our quota
// then we mark the wall opening with a door
this.SetCell(newx, newy, Tile.Door);
// clean up infront of the door so we can reach it
this.SetCell(newx + xmod, newy + ymod, Tile.DirtFloor);
}
}
else if (feature >= ChanceRoom)
{ // new corridor
if (this.MakeCorridor(newx + xmod, newy + ymod, 6, validTile.Value))
{
// same thing here, add to the quota and a door
currentFeatures++;
this.SetCell(newx, newy, Tile.Door);
}
}
发现它实际上只从“房间”和“过道”中选择。选择后调用 MakeRoom 或 MakeCorridor 进行建造并且放上门。
我查看了他游戏的Java源代码,发现实际他在游戏中设计了更多的元素:
// choose new feature to add
switch (c) {
case 'c' :
return makeCorridor(m,x, y, dx, dy);
case 'o' :
return makeOvalRoom(m,x, y, dx, dy);
case 'z' :
return makeMaze(m,x,y,dx,dy);
case 'r' :
return makeRoom(m,x,y,dx,dy);
case 't' :
return makeCorridorToRoom(m,x, y, dx, dy);
case 'h' :
return makeChamber(m,x, y, dx, dy);
case 'n' :
return makeTunnel(m,x, y, dx, dy);
case 's' :
return makeSquare(m,x, y, dx, dy);
case 'k' :
return makeLinkingCorridor(m,x, y, dx, dy);
default:
Game.warn("Dungeon extention '"+c+"' not recognised!");
return false;
}
未来有机会可以尝试一下它的这些元素。
不过,这种元素应该是因游戏而异的,如果想要用这种思路创建自己的地牢,应该设计自己游戏独特的元素
推荐阅读