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

效果展示

总结

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

相关推荐
AA陈超9 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P05-11 消息小部件
c++·游戏·ue5·游戏引擎·虚幻
AA陈超11 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P06-09 玩家等级与战斗接口
c++·游戏·ue5·游戏引擎·虚幻
takashi_void1 天前
本地实现斯坦福小镇(利用大语言模型使虚拟角色自主发展剧情)类似项目“Microverse”
人工智能·语言模型·自然语言处理·godot·游戏程序·斯坦福小镇
开发游戏的老王1 天前
虚幻引擎虚拟制片入门教程 之 Sequencer 常用技巧
游戏引擎·虚幻
开发游戏的老王2 天前
虚幻引擎入门教程:虚幻编辑器的基本操作
编辑器·游戏引擎·虚幻
AA陈超2 天前
虚幻引擎5 GAS开发俯视角RPG游戏 P05-08 UI 部件数据表
c++·游戏·ue5·游戏引擎·虚幻
向宇it2 天前
【unity实战】MapMagic 2实战例子
游戏·3d·unity·c#·游戏引擎
SlowFeather2 天前
Unity TMP可控角度多色渐变文字
unity·游戏引擎
霜绛2 天前
Unity:UGUI笔记(一)——三大基础控件、组合控件
笔记·学习·unity·游戏引擎