[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);
        }
    }

效果展示

总结

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

相关推荐
南無忘码至尊20 小时前
Unity学习90天-第1天-认识Transform + 坐标系
学习·unity·游戏引擎
南無忘码至尊21 小时前
Unity学习90天-第1天-认识Unity并书写我们的第一个脚本
学习·unity·游戏引擎
风酥糖1 天前
Godot游戏练习01-第26节-轮次结束后弹出升级选项
游戏·游戏引擎·godot
雪域迷影1 天前
Hazel游戏引擎结构分析
c++·游戏引擎·hazel
weixin_409383121 天前
godot创建两种敌人僵尸 一种吐舌头 一种在角色脚下生成圆形伤害圈 两种僵尸均继承enemy脚本 理解继承
游戏引擎·godot
mxwin2 天前
Unity Shader 跨平台兼容性:处理纹理坐标翻转与精度差异
unity·游戏引擎
王家视频教程图书馆2 天前
godot 下载地址
游戏引擎·godot
small-pudding2 天前
Unity URP + Compute Shader 路径追踪器实战:从可用到可优化
unity·游戏引擎
weixin_423995002 天前
unity 物体转向鼠标点击方向2d和3d
unity·计算机外设·游戏引擎
mxwin2 天前
Unity URP 下 Shader 变体 (Variants):multi_compile 与 shader_feature的关键字管理及变体爆炸防控策略
unity·游戏引擎