[Godot] C#简单实现2D节点图生成

我需要做一个随机的2D节点图,用来作为游戏的大地图,对于我这种简单的需求,完全可以在划定地图长宽和最小距离后,直接全随机生成,当然,这样就显得不够"优雅",在某些情况下还会有空洞或不均匀等问题,这里我就给大家分享一下两个简单的实现方法

实现过程

泊松盘采样

简单来说,泊松盘采样就是通过现有点来生成点集,规范的还会有网格加速活跃点列表来进行生成优化,对于我要实现的效果,这些优化暂时是不需要的

特性
  • 从一个随机起点开始,逐步生成新点。

  • 新点基于已有点,随机选择一个方向和距离(在某个范围内),并检查是否满足最小距离约束。

  • 如果新点满足约束(不与其他点太近且在边界内),则加入点集;否则放弃并重新尝试。

代码实现

代码部分

简单泊松盘采样
cs 复制代码
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;

public partial class PointGenerate : Node2D
{
    //大地图点生成

    [Export] public int mapX;       //长
    [Export] public int mapY;       //宽
    [Export] public int pointCount;     //数量
    [Export] public int tryCount;       //尝试次数
    [Export] public float mixLength;        //最小距离

    private List<PointScript> points = new();       //地图节点集

    [ExportCategory("Node")]
    [Export] public PackedScene testPoint;      //测试节点
    [Export] public Node2D mapPoints;       //挂载节点

    public override void _Ready()
    {
        PointMap();
    }

    public override void _Process(double delta)
    {
        if (Input.IsKeyPressed(Key.Space))        //为了方便调试用空格生成
            PointMap();
    }

    private void PointMap()         //点生成
    {
        mapPoints.GetChildren().ToList().ForEach(child => child.QueueFree());
        points.Clear();
        
        var firstPoint = testPoint.Instantiate() as PointScript;
        float pointX = GD.RandRange(0, mapX);
        float pointY = GD.RandRange(0, mapY);
        firstPoint.Position = new Vector2(pointX, pointY);
        points.Add(firstPoint);
        mapPoints.AddChild(firstPoint);

        int attempts = 0;
        while (points.Count < pointCount && attempts < tryCount * points.Count){
            attempts++;

            var basePoint = points[GD.RandRange(0, points.Count - 1)];

            float angle = GD.Randf() * MathF.Tau;
            float dist = (float)GD.RandRange(mixLength, mixLength * 2f);
            Vector2 newPoint = basePoint.Position + new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * dist;

            //边界检查
            if (newPoint.X < 0 || newPoint.Y < 0 || newPoint.X > mapX || newPoint.Y > mapY)
                continue;

            //点距离检查
            bool isDist = false;
            foreach (var p in points)
            {
                if (p.Position.DistanceTo(newPoint) < mixLength)
                {
                    isDist = true;
                    break;
                }
            }
            if (isDist)
                continue;

            var point = testPoint.Instantiate() as PointScript;
            point.Position = newPoint;
            points.Add(point);
            mapPoints.AddChild(point);
        }
    }

}
简单随机
cs 复制代码
private void PointMap()
    {
        mapPoints.GetChildren().ToList().ForEach(child => child.QueueFree());
        points.Clear();

        int attempts = 0;
        while (points.Count < pointCount && attempts < tryCount)
        {
            attempts++;

            float pointX = GD.RandRange(0, mapX);
            float pointY = GD.RandRange(0, mapY);
            Vector2 newPoint = new Vector2(pointX, pointY);

            //点距离检查
            bool isDist = false;
            foreach (var p in points)
            {
                if (p.Position.DistanceTo(newPoint) < mixLength)
                {
                    isDist = true;
                    break;
                }
            }
            if (isDist)
                continue;

            var point = testPoint.Instantiate() as PointScript;
            point.Position = newPoint;
            points.Add(point);
            mapPoints.AddChild(point);
        }
    }

效果展示

总结

还有很多问题,比如形状和分布问题,还可能会有点生成缺失问题(可以将边界检查去掉),大家可以根据自己的需要进行修改

相关推荐
Avalon71211 小时前
Unity3D响应式渲染UI框架UniVue
游戏·ui·unity·c#·游戏引擎
风酥糖13 小时前
Godot游戏练习01-第33节-新增会爆炸的敌人
游戏·游戏引擎·godot
郑寿昌1 天前
UE5与UE6在Lumen和Nanite的差异解析
游戏引擎·图形渲染·着色器
郝学胜-神的一滴1 天前
罗德里格斯旋转公式(Rodrigues‘ Rotation Formula)完整推导
c++·unity·godot·图形渲染·three.js·unreal
郑寿昌1 天前
UE6 AI加速Lumen光线追踪降噪技术解析
人工智能·游戏引擎
晴夏。1 天前
GAS下的网络同步的全面分析【超级全面】
游戏引擎·ue·gas·网络同步
田鸡_2 天前
Unity新输入系统(Input System)教学篇
unity·游戏引擎·游戏程序
EQ-雪梨蛋花汤2 天前
【Unity笔记】Unity 音游模板与免费资源:高效构建节奏游戏开发全指南
笔记·unity·游戏引擎
微莱羽墨2 天前
零、0基础入门Unity 安装详细教程(2026最新版教程,安装Unity看这一篇就够了!)
unity·游戏引擎·unity安装
nnsix2 天前
Unity 刚体的 默认力、瞬时力 区别
unity·游戏引擎