欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

试一试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工程
生成的一些结果如下:
试一试Tyrant地牢生成算法
试一试Tyrant地牢生成算法
试一试Tyrant地牢生成算法
生成的速度很快(虽然目前元素还比较少)
试一试Tyrant地牢生成算法

分析

算法思路概括起来就是:
选一个元素,尝试修建,如果成功了就继续,失败的话就再来。
我觉得关键点在于元素的设计。我研究了这段算法中这部分代码:

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

未来有机会可以尝试一下它的这些元素
不过,这种元素应该是因游戏而异的,如果想要用这种思路创建自己的地牢,应该设计自己游戏独特的元素

相关标签: 游戏开发 游戏