4. 程序化生成
2026/4/14大约 3 分钟
程序化生成
程序化生成就是"用代码而不是手工来创造内容"。比如《我的世界》的地图不是设计师一个个方块摆出来的,而是算法自动生成的——每次开新地图都不一样。这一章教你如何用算法生成地形、地牢、道具摆放等随机但合理的内容。
本章你将学到
- 噪声算法(Perlin Noise、Simplex Noise)是什么、为什么适合生成自然地形
- 如何生成随机但"连通"的地牢房间
- 道具摆放算法:保证物品分布合理不扎堆
- 关卡随机化的基本思路
噪声算法:让随机看起来"自然"
普通的随机数(比如掷骰子)每个结果互相独立,生成的地形像锯齿一样乱糟糟。噪声算法不同——它生成的随机值是"连续的",相邻的值变化平滑,就像自然界的山丘一样有高有低但不突兀。
Godot 内置了 FastNoiseLite 类,支持多种噪声算法,直接调用就行。
代码示例:用噪声生成高度图地形
C#
using Godot;
public partial class ProceduralTerrain : Node3D
{
[Export] public int MapSize { get; set; } = 64;
[Export] public float NoiseScale { get; set; } = 0.1f;
[Export] public float HeightScale { get; set; } = 15.0f;
public override void _Ready()
{
// 创建噪声生成器
var noise = new FastNoiseLite();
noise.NoiseType = FastNoiseLite.NoiseTypeEnum.Perlin;
noise.Seed = (int)GD.Randi(); // 随机种子,每次运行结果不同
noise.Frequency = NoiseScale;
var surfaceTool = new SurfaceTool();
surfaceTool.Begin(Mesh.PrimitiveType.Triangles);
for (int z = 0; z < MapSize; z++)
{
for (int x = 0; x < MapSize; x++)
{
float height = noise.GetNoise2D(x, z) * HeightScale;
surfaceTool.SetUV(new Vector2((float)x / MapSize, (float)z / MapSize));
surfaceTool.AddVertex(new Vector3(x, height, z));
}
}
surfaceTool.GenerateNormals();
var meshInstance = new MeshInstance3D();
meshInstance.Mesh = surfaceTool.Commit();
AddChild(meshInstance);
}
}GDScript
extends Node3D
@export var map_size: int = 64
@export var noise_scale: float = 0.1
@export var height_scale: float = 15.0
func _ready():
# 创建噪声生成器
var noise = FastNoiseLite.new()
noise.noise_type = FastNoiseLite.TYPE_PERLIN
noise.seed = randi() # 随机种子,每次运行结果不同
noise.frequency = noise_scale
var surface_tool = SurfaceTool.new()
surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES)
for z in range(map_size):
for x in range(map_size):
var height = noise.get_noise_2d(x, z) * height_scale
surface_tool.set_uv(Vector2(float(x) / map_size, float(z) / map_size))
surface_tool.add_vertex(Vector3(x, height, z))
surface_tool.generate_normals()
var mesh_instance = MeshInstance3D.new()
mesh_instance.mesh = surface_tool.commit()
add_child(mesh_instance)随机地牢的基本思路
生成地牢的常用方法是"房间+走廊":
- 在地图上随机撒一些矩形"房间"
- 检查房间是否重叠,去掉重叠的
- 用走廊把相邻的房间连起来
- 在走廊和房间边缘放墙壁、地板
这种方法生成的地图既有随机性,又保证所有房间都能走到。
道具摆放:用泊松圆盘采样
泊松圆盘采样(Poisson Disk Sampling)是一种保证物品之间有最小间距的随机摆放算法。它会确保道具不会扎堆,也不会太稀疏,看起来自然合理。
