using Godot; using System; using Godot.Collections; public partial class World : Node2D { public enum GeneratorAlgorithm { Random, Simple, Complex } Vector2I _darkGras = new Vector2I(0, 0); Vector2I _brightGras = new Vector2I(1, 0); Vector2I _flower = new Vector2I(2, 0); TileMapLayer _tileMapLayer; Vector2 _screenSize; float _worldWidth; float _worldHeight; private Vector2I _tileSize; private Timer _generationTimeout; [Export] public GeneratorAlgorithm Algorithm = GeneratorAlgorithm.Random; private void GenerateGrid() { Dictionary grid = new Dictionary(); for (int x = 0; x < _worldHeight; x++) { for (int y = 0; y < _worldWidth; y++) { // grid[new Vector2(x, y)] = null; } } } private Vector2 gridToWorld(Vector2 pos) => pos * _tileSize.X; // private Vector2 worldToGrid(Vector2 pos) => Godot.Mathf.Floor(pos / _tileSize.X); public override void _Ready() { GD.Print("World Node Ready"); GD.Print("Getting Screen Size"); _screenSize = GetViewportRect().Size; GD.Print("Setting World Size"); _worldWidth = _screenSize.X; _worldHeight = _screenSize.Y; GD.Print("Getting Tilemap Layer and Setting Tile Size"); _tileMapLayer = GetNode("TileMapLayer"); _tileSize = _tileMapLayer.TileSet.TileSize; GD.Print("Getting Timer"); _generationTimeout = GetNode("GenerationTimeout"); // Grid generation GD.Print("Setting Grid Properties"); Node2D grid = GetNode("Grid"); grid.Set("width", _worldHeight / _tileSize.X); grid.Set("height", _worldHeight / _tileSize.Y); grid.Set("cell_size", _tileSize); GD.Print("Calling generateGrid"); grid.Call("generateGrid"); GD.Print("Randomizing Seed"); GD.Randomize(); // World generation GD.Print("Generating World"); if (_generationTimeout.IsNodeReady()) GenerateWorld(); } // public override void _Process(double delta) // { // GD.Print(algorithm); // // } private void GenerateWorld() { try { if (_generationTimeout.IsStopped()) { switch (Algorithm) { case GeneratorAlgorithm.Random: GenerateWorldRandom(); break; case GeneratorAlgorithm.Simple: GenerateWorldSimplexNoise(); break; case GeneratorAlgorithm.Complex: GenerateWorldComplex(); break; default: break; } } _generationTimeout.Start(); } catch (Exception e) { GD.PrintErr(e); } } private void GenerateWorldRandom() { for (int y = 0; y < _worldHeight; y++) { for (int x = 0; x < _worldWidth; x++) { float rnd = GD.Randf(); if (rnd < .7f) _tileMapLayer.SetCell(new Vector2I(x, y), 0, _darkGras); else if (rnd < .9f) _tileMapLayer.SetCell(new Vector2I(x, y), 0, _brightGras); else _tileMapLayer.SetCell(new Vector2I(x, y), 0, _flower); } } } private void GenerateWorldSimplexNoise() { var noise = new FastNoiseLite(); noise.Seed = GD.RandRange(int.MinValue, int.MaxValue); noise.FractalOctaves = 2; for (int y = 0; y < _worldHeight; y++) { for (int x = 0; x < _worldWidth; x++) { var rnd = noise.GetNoise2D(x, y); // var xRnd = noise.GetNoise1D(x); // var yRnd = noise.GetNoise1D(y); if (rnd < .3f) _tileMapLayer.SetCell(new Vector2I(x, y), 0, _darkGras); else if (rnd < .6f) _tileMapLayer.SetCell(new Vector2I(x, y), 0, _brightGras); else _tileMapLayer.SetCell(new Vector2I(x, y), 0, _flower); // if (yRnd < .3f) // tileMapLayer.SetCell(new Vector2I(x, y), 0, darkGras); // else if (xRnd < .6f) // tileMapLayer.SetCell(new Vector2I(x, y), 0, brightGras); // else // tileMapLayer.SetCell(new Vector2I(x, y), 0, flower); } } } [ExportGroup("General")] [Export] public FastNoiseLite.NoiseTypeEnum NoiseType { get => _noiseType; set { _noiseType = value; GenerateWorld(); } } [Export] public int NoiseSeed { get => _noiseSeed; set { _noiseSeed = value; GenerateWorld(); } } [Export] public Vector3 NoiseOffset { get => _noiseOffset; set { _noiseOffset = value; GenerateWorld(); } } [ExportGroup("Perlin and Simplex")] [Export] public float NoiseFrequency { get => _noiseFrequency; set { _noiseFrequency = value; GenerateWorld(); } } [Export] public FastNoiseLite.FractalTypeEnum NoiseFractalType { get => _noiseFractalType; set { _noiseFractalType = value; GenerateWorld(); } } [Export] public int NoiseFractalOctaves { get => _noiseFractalOctaves; set { _noiseFractalOctaves = value; GenerateWorld(); } } [Export] public float NoiseFractalLacunarity { get => _noiseFractalLacunarity; set { _noiseFractalLacunarity = value; GenerateWorld(); } } [Export] public float NoiseFractalGain { get => _noiseFractalGain; set { _noiseFractalGain = value; GenerateWorld(); } } [Export] public float NoiseFractalWeightedStrength { get => _noiseFractalWeightedStrength; set { _noiseFractalWeightedStrength = value; GenerateWorld(); } } [Export] public float NoiseFractalPingPongStrength { get => _noiseFractalPingPongStrength; set { _noiseFractalPingPongStrength = value; GenerateWorld(); } } [ExportGroup("Cellular")] [Export] public float NoiseCellularJitter { get => _noiseCellularJitter; set { _noiseCellularJitter = value; GenerateWorld(); } } [Export] public FastNoiseLite.CellularDistanceFunctionEnum NoiseCellularDistanceFunction { get => _noiseCellularDistanceFunction; set { _noiseCellularDistanceFunction = value; GenerateWorld(); } } [Export] public FastNoiseLite.CellularReturnTypeEnum NoiseCellularReturnType { get => _noiseCellularReturnType; set { _noiseCellularReturnType = value; GenerateWorld(); } } [ExportGroup("Domain Warp")] [Export] public bool NoiseDomainWarpEnabled { get => _noiseDomainWarpEnabled; set { _noiseDomainWarpEnabled = value; GenerateWorld(); } } [Export] public FastNoiseLite.DomainWarpTypeEnum NoiseDomainWarpType { get => _noiseDomainWarpType; set { _noiseDomainWarpType = value; GenerateWorld(); } } [Export] public float NoiseDomainWarpAmplitude { get => _noiseDomainWarpAmplitude; set { _noiseDomainWarpAmplitude = value; GenerateWorld(); } } [Export] public float NoiseDomainWarpFrequency { get => _noiseDomainWarpFrequency; set { _noiseDomainWarpFrequency = value; GenerateWorld(); } } [Export] public FastNoiseLite.DomainWarpFractalTypeEnum NoiseDomainWarpFractalType { get => _noiseDomainWarpFractalType; set { _noiseDomainWarpFractalType = value; GenerateWorld(); } } [Export] public int NoiseDomainWarpFractalOctaves { get => _noiseDomainWarpFractalOctaves; set { _noiseDomainWarpFractalOctaves = value; GenerateWorld(); } } [Export] public float NoiseDomainWarpFractalLacunarity { get => _noiseDomainWarpFractalLacunarity; set { _noiseDomainWarpFractalLacunarity = value; GenerateWorld(); } } [Export] public float NoiseDomainWarpFractalGain { get => _noiseDomainWarpFractalGain; set { _noiseDomainWarpFractalGain = value; GenerateWorld(); } } // General private int _noiseSeed; private FastNoiseLite.NoiseTypeEnum _noiseType; // Simplex and Perlin private float _noiseFrequency = 0.01f; private Vector3 _noiseOffset = new(0.0f, 0.0f, 0.0f); private FastNoiseLite.FractalTypeEnum _noiseFractalType = FastNoiseLite.FractalTypeEnum.Fbm; private int _noiseFractalOctaves = 5; private float _noiseFractalLacunarity = 2.0f; private float _noiseFractalGain = 0.5f; private float _noiseFractalWeightedStrength = 0.0f; private float _noiseFractalPingPongStrength = 2.0f; // Cellular private float _noiseCellularJitter = 1.0f; private FastNoiseLite.CellularDistanceFunctionEnum _noiseCellularDistanceFunction; private FastNoiseLite.CellularReturnTypeEnum _noiseCellularReturnType = FastNoiseLite.CellularReturnTypeEnum.Distance; // Domain Warp private bool _noiseDomainWarpEnabled = false; private FastNoiseLite.DomainWarpTypeEnum _noiseDomainWarpType = FastNoiseLite.DomainWarpTypeEnum.SimplexReduced; private float _noiseDomainWarpAmplitude = 30.0f; private float _noiseDomainWarpFrequency = 0.05f; private FastNoiseLite.DomainWarpFractalTypeEnum _noiseDomainWarpFractalType = FastNoiseLite.DomainWarpFractalTypeEnum.Progressive; private int _noiseDomainWarpFractalOctaves = 5; private float _noiseDomainWarpFractalLacunarity = 6.0f; private float _noiseDomainWarpFractalGain = 0.5f; private void GenerateWorldComplex() { var noise = new FastNoiseLite(); if (NoiseSeed == 0) noise.Seed = GD.RandRange(int.MinValue, int.MaxValue); else noise.Seed = NoiseSeed; GD.Print(noise.Seed); noise.NoiseType = _noiseType; noise.Frequency = _noiseFrequency; noise.Offset = _noiseOffset; noise.FractalType = _noiseFractalType; noise.FractalOctaves = _noiseFractalOctaves; noise.FractalLacunarity = _noiseFractalLacunarity; noise.FractalGain = _noiseFractalGain; noise.FractalWeightedStrength = _noiseFractalWeightedStrength; noise.FractalPingPongStrength = _noiseFractalPingPongStrength; noise.CellularJitter = _noiseCellularJitter; noise.CellularReturnType = _noiseCellularReturnType; noise.DomainWarpEnabled = _noiseDomainWarpEnabled; noise.DomainWarpType = _noiseDomainWarpType; noise.DomainWarpAmplitude = _noiseDomainWarpAmplitude; noise.DomainWarpFrequency = _noiseDomainWarpFrequency; noise.DomainWarpFractalType = _noiseDomainWarpFractalType; noise.DomainWarpFractalOctaves = _noiseDomainWarpFractalOctaves; noise.DomainWarpFractalLacunarity = _noiseDomainWarpFractalLacunarity; noise.DomainWarpFractalGain = _noiseDomainWarpFractalGain; for (int y = 0; y < _worldHeight; y++) { for (int x = 0; x < _worldWidth; x++) { var rnd = noise.GetNoise2D(x, y); if (rnd < .3f) _tileMapLayer.SetCell(new Vector2I(x, y), 0, _darkGras); else if (rnd < .6f) _tileMapLayer.SetCell(new Vector2I(x, y), 0, _brightGras); else _tileMapLayer.SetCell(new Vector2I(x, y), 0, _flower); } } } }