C# 如何在无限贴图增长时连续生成柏林噪声?
编辑:我最终使用了在这里找到的FastNoise库:它拥有人们可能需要产生许多不同种类噪音的所有东西。正如标题可能暗示的那样,它也相当快 我正在创造一个2D无限的,程序生成的世界。当播放器移动时,我从光盘上加载和卸载块。我正在使用一个细胞自动机函数来定义每个区块内的局部瓷砖是如何设计的,但我需要噪声(在本例中是柏林)来定义创建新区块时每个区块的生物群落类型。我理解如何转换0到1之间的小数来表示这一点,我唯一的问题是,我在创建柏林噪波时遵循的教程要求您传递预定义的2d数组并返回相同大小的噪波数组。因为我的世界是动态增长的,所以我对如何使用固定大小的数组来指定新的块类型有点困惑 我看到的其他答案并没有完全涵盖如何处理噪音产生的无限部分。我最好的猜测是,我需要以某种方式用每个新创建的块生成或扩展噪声,尽管我如何做让我感到困惑 下面是我从这里翻译成C#的一些代码: 诚然,这里的一些数学我还没有完全理解,尤其是按位函数C# 如何在无限贴图增长时连续生成柏林噪声?,c#,xna,monogame,procedural-generation,C#,Xna,Monogame,Procedural Generation,编辑:我最终使用了在这里找到的FastNoise库:它拥有人们可能需要产生许多不同种类噪音的所有东西。正如标题可能暗示的那样,它也相当快 我正在创造一个2D无限的,程序生成的世界。当播放器移动时,我从光盘上加载和卸载块。我正在使用一个细胞自动机函数来定义每个区块内的局部瓷砖是如何设计的,但我需要噪声(在本例中是柏林)来定义创建新区块时每个区块的生物群落类型。我理解如何转换0到1之间的小数来表示这一点,我唯一的问题是,我在创建柏林噪波时遵循的教程要求您传递预定义的2d数组并返回相同大小的噪波数组。
public class PerlinNoiseGenerator
{
public int OctaveCount { get; set; }
public float Persistence { get; set; }
public PerlinNoiseGenerator(int octaveCount, float persistence)
{
this.OctaveCount = octaveCount;
this.Persistence = persistence;
}
public float[,] GenerateWhiteNoise(int width, int height)
{
float[,] noiseFieldToReturn = new float[width, height];
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
noiseFieldToReturn[i, j] = (float)Game1.Utility.RGenerator.NextDouble() % 1;
}
}
return noiseFieldToReturn;
}
public float[,] SmoothNoiseField(float[,] whiteNoise, int octave)
{
int width = whiteNoise.GetLength(0);
int height = whiteNoise.GetLength(1);
float[,] smoothField = new float[width, height];
int samplePeriod = 1 << octave;
float sampleFrequency = 1.0f / samplePeriod;
for(int i =0; i < width; i++)
{
int samplei0 = (i / samplePeriod) * samplePeriod;
int samplei1 = (samplei0 + samplePeriod) % width;
float horizontalBlend = (i - samplei0) * sampleFrequency;
for(int j =0; j < height; j++)
{
int samplej0 = (j/samplePeriod) * samplePeriod;
int samplej1 = (samplej0 + samplePeriod) % height;
float verticalBlend = (j - samplej0) * sampleFrequency;
float top = LinearInterpolate(whiteNoise[samplei0, samplej0],
whiteNoise[samplei1, samplej0], horizontalBlend);
float bottom = LinearInterpolate(whiteNoise[samplei0, samplej1],
whiteNoise[samplei1, samplej1], horizontalBlend);
smoothField[i, j] = LinearInterpolate(top, bottom, verticalBlend);
}
}
return smoothField;
}
public float[,] GeneratePerlinNoise(float[,] baseNoise, int octaveCount)
{
int width = baseNoise.GetLength(0);
int height = baseNoise.GetLength(1);
float[][,] smoothNoise = new float[octaveCount][,];
float persistance = .5f;
for(int i =0; i < octaveCount;i++)
{
smoothNoise[i] = SmoothNoiseField(baseNoise, i);
}
float[,] perlinNoise = new float[width, height];
float amplitude = 1f;
float totalAmplitude = 0.0f;
for(int octave = octaveCount - 1; octave > 0; octave-- )
{
amplitude *= persistance;
totalAmplitude += amplitude;
for(int i =0; i < width;i++)
{
for(int j =0; j < height; j++)
{
perlinNoise[i, j] += smoothNoise[octave][i, j] * amplitude;
}
}
}
for(int i =0; i < width; i++)
{
for(int j =0; j < height; j++)
{
perlinNoise[i, j] /= totalAmplitude;
}
}
return perlinNoise;
}
public float LinearInterpolate(float a, float b, float alpha)
{
return a * (1 - alpha) + alpha * b;
}
}
公共类PerlinNoiseGenerator
{
公共int-OctaveCount{get;set;}
公共浮点持久性{get;set;}
公共PerlinNoiseGenerator(整数八进制计数、浮点持久性)
{
this.OctaveCount=OctaveCount;
这个。坚持=坚持;
}
公共浮点数[,]生成白噪声(整数宽度,整数高度)
{
浮动[,]noiseFieldToReturn=新浮动[宽度,高度];
对于(int i=0;i
这段代码应该编译并生成一个固定大小的噪声数组您要确保的主要事情是起始随机噪声是伪随机的,因此坐标始终有一个“固定随机值” 这可能是你必须重写你的随机噪声发生器,使用坐标作为输入。我想你的地图有一个随机的种子数,所以你可以用这篇文章作为起点,加上1个因子: 为了给你的地图制作带来一些灵感,我不久前写了这篇文章: 在您的评论之后添加:您需要更改的唯一功能是GenerateWhiteNoise。我不会说C#,但这是总体思路:
GenerateWhiteNoise(int x_start_coord, int y_start_coord, int random_seed) {
int default_x_width = 100;
int default_y_heigth = 50;
float[,] noiseFieldToReturn = new float[width, height];
for (in x = x_start_coord; i < default_x_width + x_start_coord; x++)
{
for (in y = y_start_coord; i < default_y_width + y_start_coord; y++)
{
noiseFieldToReturn[i, j] = (float)pseudo_rnd_value(x, y, random_seed);
}
}
return noiseFieldToReturn;
}
GenerateWhiteNoise(int x_start_coord,int y_start_coord,int random_seed){
int default_x_width=100;
int默认值_y_高度=50;
浮动[,]noiseFieldToReturn=新浮动[宽度,高度];
对于(在x=x\u开始协调;i
这将为您提供构建地图分幅所需的伪随机值,您唯一需要的是播放器的坐标(x和y)。您可能正在寻找类似的东西:这一切归结为使用
perlinNoise[i,j]和宽度、高度。我没有时间帮你了。谢谢你的回复。你的Excel地图很酷。然而,我不确定如何解释你所联系的问题。我知道我需要使用坐标作为输入,但我不知道如果不引用一组2D数组(就像你在你的数组中所做的那样),我该怎么做。用一些模型代码更新了我的答案,这有帮助吗?