C++ 游戏开发中怎么实现基于波函数的程序化地牢自动生成(WFC算法)

胖瑶酱_8322

胖瑶酱_8322

2026-11-02

959人浏览

原创

WFC适用于生成结构化、接口约束明确的地牢(如城堡、模块化建筑),而非连通性优先的迷宫;C++实现需手写tile结构体与方向接口ID,用位掩码+查表优化熵计算,BFS传播防栈溢出,并必须实现回退机制。

c++ 游戏开发中怎么实现基于波函数的程序化地牢自动生成(wfc算法)

WFC 在 C++ 游戏中做地牢生成,不是“能不能”,而是“要不要承担它的开销”。它能产出高度结构化、约束明确的布局(比如房间必须连走廊、门必须对齐墙),但不擅长生成连通性优先的迷宫式地牢——那更适合 BSP 或 Prim 算法。如果你要的是“每扇门都严丝合缝接上另一扇门”的城堡、城市街区或模块化建筑,WFC 才是正解。

WFC 的核心不是图像采样,而是 tile 接口约束定义

很多初学者直接拿 WFC 去处理像素图,结果卡在边缘匹配逻辑里。C++ 实现地牢 WFC,第一步必须跳过图像解析,直接手写 tile 元数据:

  • tile 不是图片,而是一个带 4 个方向接口(up/down/left/right)的结构体,每个接口填一个整数 ID(如 0 表示“可通行走廊”,1 表示“实心墙”,2 表示“门”)
  • 约束表本质是二维数组:compatible[up_id][down_id] → true 表示允许上下拼接;同理定义 left-right 和 up-down 的兼容关系
  • 别用 map> 存兼容表——查找慢;用 std::array<:array>, 8>(假设最多 8 种接口 ID)更高效
  • 常见错误:door tile 的 up 和 down 都设为 2,但忘了在兼容表里加 compatible[2][2] = true,导致无法垂直堆叠门

熵计算与坍缩必须用 std::vector + 位掩码优化

每个格子初始状态是“所有 tile 都可能”,即一个长度为 N 的布尔向量。但 N 一过百,每次遍历求熵(非零项计数)就成性能瓶颈。实际工程中应:

3D 游戏开发(Godot 4)
3D 游戏开发(Godot 4)

用 Godot 4 + GDScript 开发 3D 游戏的端到端工作流。触发场景:"做一个 3D 游戏"、 "第一人称/第三人称/FPS/TPS/3D 平台跳跃"、"用 Godot 做 3D"、"加个 3D 角色控制器/ 相机/敌人寻路/关卡"、"导入 glb 模型不显示"、"3D 场景太暗/太卡"、"make a 3D game"、 "first-per

下载
  • 把 tile ID 映射为 bit 位:第 0 个 tile → bit 0,第 1 个 → bit 1……用 uint64_t 存最多 64 种 tile;超 64 就分两组,避免 std::vector 的代理引用开销
  • 熵值不实时计算,改用预存的 popcount 查表:static constexpr uint8_t POPCOUNT[256] = { ... };,每次更新 bitset 后查低 8 位、中 8 位、高 8 位即可
  • 坍缩时,不是“随机选一个剩余 tile”,而是先找最小熵格子(熵 == 1 的优先),再从它的 bitset 中用 __builtin_ctzll(mask) 取最低位——比 std::rand() 快且确定性更强,方便调试
  • 错误现象:用 std::vector 存候选 tile ID,每次坍缩都 erase,导致大量内存移动;实际应只维护 bitset,坍缩后才批量重建索引

传播阶段最容易栈溢出或死循环

一个格子坍缩后,要通知四邻格更新其可能 tile 集合。这个过程若不做剪枝,会无限递归或反复触发同一格子。关键控制点:

  • 传播必须用队列(BFS),不是递归(DFS)——避免深调用栈炸掉,尤其在 128×128 地图上
  • 每个格子加访问标记(propagated[i][j]),入队前检查是否已入队;清空队列后统一重置标记,别在传播中实时改
  • 约束检查必须严格:邻居格子当前所有剩余 tile 中,至少有一个能在对应方向匹配本格子的接口 ID;一个都不匹配 → 冲突(contradiction)→ 必须回退
  • 没实现回退机制?那就别用 WFC 做地牢生成。最简回退就是保存最近 3 层状态快照(用 std::vector<:vector>>),冲突时 rollback 并换一个坍缩选项;否则程序直接 abort

真正难的从来不是“怎么让波函数塌缩”,而是“怎么定义哪些塌缩结果算‘地牢’”。比如你允许 room tile 四周全是 wall,那生成出来的就是孤岛房间;但加一条约束“每个 room 至少有一个方向接口是 door”,整个逻辑就变复杂——这些语义规则不会自动出现,得你一行行写进兼容表和传播条件里。WFC 是把设计决策编译成约束的工具,不是魔法生成器。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

在线游戏
在线游戏

海量精品小游戏合集,无需安装即点即玩,休闲益智、动作闯关应有尽有,秒开即玩,轻松解压,快乐停不下来

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2288

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

347

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1429

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1237

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ 手册教程
C++ 手册教程

共41课时 | 78.6万人学习

C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习