在以撒的结合中生成地牢



《以撒的结合》及其重制《以撒的结合:重生》是我最喜欢的游戏。它们属于流氓双棍射击游戏类型,与Enter the Gungeon非常相似



这些游戏产生的地牢尤其著名。我在互联网上看过无数关于如何创建Isaac风格的一代的教程,但我想知道它是如何在原始版本中实现的。令我惊讶的是,大多数教程都错误地描述了该过程。在本文中,我将讨论生成的工作原理,并在Javascript演示中显示其示例。



尽管我不得不反编译和刷新我尘土飞扬的Flash知识(我曾经写过自己的Actionscript反编译器),但我也很幸运:开发人员IsaacFlorian Himsl和Rebirth的核心开发人员之一Simon Parser高兴地回答了我的问题。实际上,Florian甚至最近录制了一段描述该算法视频在他的频道上,您还可以找到他的新游戏Squid Invaders的开发细节。



考虑到他的故事的存在,我的文章可以被认为是多余的,但是如果您想了解一些流血的细节,请继续阅读。



基本算法



Isaac的开发人员深受Zelda系列2D游戏的启发,并生成了与他们的地牢相似的地图。





这是一组由边相互连接的方形房间。有些房间很特别-每层总是有商店,藏宝室和老板;此外,还随机选择了其他几个特殊房间。除秘密房间外,地牢中没有回路。



游戏本身包含这种级别的线性通道,通常每个“章节”都有两个级别。在通过过程中,地图会变大一些,房间的内容也会发生变化,但实际上每次创建地图的算法都是相同的。



艾萨克(Isaac)的第一个版本在不到3个月的时间内开发完毕,因此希姆斯卢不得不非常高效地利用他的时间。游戏的基本设计时尚而简单。首先,生成平面图(级别)。然后选择一些房间作为特别房间。然后从相应的池中选择每个房间的内部。



平面图



以撒在9x8网格上生成。为方便起见,单元格用数字表示-数字分别表示X位置,十位数-Y位置,这意味着您可以向上,向下,向左和向右移动,只需加上+ 10,-10,+ 1和-1。 X位置为0的单元格不会被使用(总是为空),这意味着大多数代码都不需要担心地图边界。也就是说,地图上左上角的单元格是01,右下角的单元格是79。



平面图仅定义了哪些单元格将包含房间-房间的内容将在以后选择。



首先,该公式random(2) + 5 + level * 2.6确定房间数。那些。级别从7或8个房间开始,每次增加2或3个房间。



然后,游戏将起始房间(单元格35)放入队列中。然后,她周期性地绕过队列。对于队列中的每个单元,它会循环遍历4个主要方向并执行以下操作:



  • 通过将+ 10 / -10 / + 1 / -1添加到当前单元格来确定相邻的单元格。
  • 如果相邻的单元格已经被占用,则该游戏不执行任何操作。
  • 如果相邻单元格本身具有多个已填充的相邻单元,则该游戏不执行任何操作。
  • 如果关卡上已经有足够的房间,则游戏将不执行任何操作。
  • 游戏不执行任何操作的可能性为50%。
  • 否则,游戏会将相邻的单元格标记为包含该房间并将其添加到队列中。


如果一个单元格未将房间添加到任何相邻的单元格中,则它是一个死胡同,可以将其添加到目标房间列表中以供进一步使用。



如果地图需要超过16个房间,则开始房间会定期重新排队以刺激增长。



由于上述算法从一个房间开始并向外扩展多次,因此实际上是广度优先的探索。如果已经有两个邻居,则不允许添加房间的限制将房间划分为多个单独的走廊,这些走廊永远不会循环在一起。



然后检查平面图的一致性。它应包含所需数量的房间,而老板房间不应位于起始房间旁边。否则,生成将重新开始。



特别房间



通过阅读终端房间列表中的最后一项来放置老板房间。由于这一代是向外生长的事实,因此这始终是离起始房间最远的房间之一。



然后指示秘密室的位置。这些房间被添加到平面图中。它们是禁止将房间放置在几个现有房间旁边的规则的少数例外之一。实际上,相反,算法更喜欢这样放置它们。生成器随机搜索至少三个房间附近而不是任何终端房间附近的空单元。如果他在300次尝试后仍未找到它,则它会稍微削弱搜索条件,而在600次尝试后,它将进一步削弱搜索条件。此过程可确保将秘密房间始终放置在水平高度上,但通常会将它们挤压在十字路口附近,这意味着它们附近总会有很多房间。



几乎所有其他特殊房间都位于随机的终端房间中。有些房间有保证,其他的则很少。例如,牺牲室出现七次之一;如果玩家处于完全健康状态,则发生的次数约为三分之一。



普通房间



相邻的房间始终在中心正好有一扇门(或易碎的墙),每个房间的设计均可从四个方向访问。因此,选择房间时无需特别考虑-任何组合都可以。



房间是从游泳池中随机选择的。有关房间的信息包含结构(坑,火,石头等)和怪物。两者都会随机变化,例如冠军怪兽和红色壁炉的出现。



对于普通房间,有三个池:简易池,中池和硬池。本章的第一阶段从中型房间选择,第二阶段从中型房间和困难房间选择。第一章(地下室)包含游泳池中的174个普通房间。像Cellar这样的“ Alternate Chapters”(替代章节)会随机替换Basement,其房间设置略有不同。



迷宫的诅咒



该代码最有趣的附加功能之一是加倍大小的地图。它们是随机创建的,并且仅用于某些挑战模式。除了特殊房间和相邻的两个老板房间的数量明显增加一倍外,它们还有许多小细节:



  • 普通房增加80%(最多45个房间)
  • 对于特殊房间,仅使用6个远端房间
  • 级别从简单,中等和复杂房间的池中选择房间。
  • 额外的普通房间被随机添加到平面图,其布局逻辑类似于秘密房间。


演示版



我用Javascript创建了生成器的简化示例,以便您可以尝试使用它。完整的代码可以在这里找到,而工作示例可以原始文章中找到





重生





以撒的捆绑:重生是由尼卡利斯Nicalis)创建的原始以撒的捆绑的翻版,当时以其VVVVVCave Story港口而闻名游戏已移植到C ++,并且所有声音和图形都已重做。多年来,该游戏获得了许多DLC,为原本已经令人印象深刻的清单增加了新的物品和敌人。



虽然重生有很多有趣的创新,但对关卡生成的主要贡献是增加了更大的不规则房间。





借助全套DLC(在撰写本文时,这是“出生后+”),游戏具有11个大房间:2×2、2×1,L形和具有不同旋转选项的狭窄走廊。





典型的L形房间,是普通房间大小的三倍。它是由Simon Parser通过仔细修改Himsla源代码实现的。



该算法没有绕过所有方向,而是绕过了房间的所有出口。在2x2的房间中,最多可以有八个。



在插入房间时,他随机尝试插入大房间。邻居检查仍然适用,但仅应用于门旁边的第一个单元;但是,算法会检查剩余空间是否足够。这意味着大房间可以创建水平循环。通常,两个大房间彼此相邻,并由连接它们的一对门来补充。



如果没有足够的空间容纳一个房间,则该算法将尝试插入另一个候选对象。如果成功插入大型房间,则有95%的可能性将其从池中删除。



处理大型老板房间甚至需要更多代码。请记住,老板房间总是离起始房间尽可能远。如果需要更大的房间,则生成器将替换预期的单人房间。由于老板房间总是死胡同,因此在更换时,算法会检查它们是否与某些其他房间相邻。有时替换仍然是不可能的,因此要检查所有端点到起始房间的最大距离,如果不合适,则算法会放弃。



对于秘密房间,将考虑布置平面图上的相邻房间,并且仅在算法确定不需要门时才选择房间。





在以撒,通常无法跨越裂缝



输出量



Isaac级别生成器并不是我见过的最复杂的级别生成器,但是尽管代码量很少,但它的运行却异常出色。这可能就是为什么他们尝试如此频繁地重新创建它的原因。如我们在重生示例中所见,它的简单性允许更改和扩展。令人难以置信的结果。



您还可以注意到,此游戏延续了与房间详细信息分开生成平面图的趋势。在关于《暗黑破坏神1》翻译成《哈布雷》)和《进入地下城》翻译成《哈布雷》)的文章中,我说了为什么这种方法非常强大。



在反编译代码时,我没有发现任何特别有趣的细节。我可以说的最有趣的是,藏宝室的位置存储在一个名为“ boner”的变量中-可能是Bonus Room的缩写。关于各种项目的轻微副作用,代码中也有一些微妙之处,但我将把这个话题留给分析仪



接下来,您可以观看Himsla游戏内部的视频系列,甚至可以玩Isaac并实时观看所有关卡。我听说今年将推出新的悔改DLC。我还建议您玩首席设计师Edmund McMillen(尤其是Super Meat Boy)的其他游戏。



All Articles