Рельеф SimplexNoise в MonoGame

Я делаю случайно сгенерированную тайловую игру в MonoGame и пытаюсь использовать Simplex Noise для создания ландшафта. Проблема в том, что я никогда раньше не использовал Simplex Noise, поэтому, как вы, наверное, догадались, мой код не работает. Он создает только плитки травы. Вот код, который я пробовал:

public void Generate() {
    Tiles = new List<Tile>();
    Seed = GenerateSeed();
    for (int x = 0; x < Width; x++) {
        for (int y = 0; y < Height; y++) {
            float value = Noise.Generate((x / Width) * Seed, (y / Height) * Seed) / 10.0f;
            if (value <= 0.1f) {
                Tiles.Add(new Tile(Main.TileGrass, new Vector2((int)x * Tile.Size, (int)y * Tile.Size)));
            }
            else if (value > 0.1f && value <= 0.5f) {
                Tiles.Add(new Tile(Main.TileSand, new Vector2((int)x * Tile.Size, (int)y * Tile.Size)));
            }
            else {
                Tiles.Add(new Tile(Main.TileWater, new Vector2((int)x * Tile.Size, (int)y * Tile.Size)));
            }
        }
    }
}

public int GenerateSeed() {
    Random random = new Random();
    int length = 8;
    int result = 0;

    for (int i = 0; i < length; i++) {
        result += random.Next(0, 9);
    }

    return result;
}

Я использую эту реализацию для создания шума .


person Wahoozel    schedule 17.05.2015    source источник


Ответы (1)


Проверьте строку 133 в SimplexNoise, который вы используете:

// The result is scaled to return values in the interval [-1,1].

После того, как вы разделите его на 10, результат будет в диапазоне от -0,1 до +0,1. Вам нужен диапазон от 0 до 1, поэтому вместо деления на 10 вам нужно:

  • Добавьте 1 (диапазон будет от 0 до 2).
  • Разделите на 2 (диапазон будет от 0 до 1).

float value = (Noise.Generate((x / Width) * Seed, (y / Height) * Seed) + 1) / 2.0f;

Или измените if/else для работы с диапазонами от -1 до +1.

if (value <= -0.8f)
{
    Tiles.Add(new Tile(Main.TileGrass, new Vector2((int)x * Tile.Size, (int)y * Tile.Size)));
}
else if (value <= 0)
{
    Tiles.Add(new Tile(Main.TileSand, new Vector2((int)x * Tile.Size, (int)y * Tile.Size)));
}
else
{
    Tiles.Add(new Tile(Main.TileWater, new Vector2((int)x * Tile.Size, (int)y * Tile.Size)));
}
person Blas Soriano    schedule 17.05.2015