如何修改Perlin Noise [参见线程中的示例]

Fai*_*Man 5 flash actionscript-3

我在2D中使用Perlin Noise作为世界发生器(如何在Terraria中使用).我发现了一个适合我的实现.我需要生成世界的一部分,但这种认识只能产生一次全世界.

实现 - http://sirisian.com/javascriptgame/tests/valuenoise2.html 我把它重写为AS3,稍加修改(+主要代码) - http://codepad.org/crMEQ2DD

请帮助修改代码,以便生成噪声部分:

PerlinNoise.randomize(65735);
...
var noises:Vector.<Number> = PerlinNoise.getNoise(0, 0, 100, 100, 6, 6, 1.0, 20);
...
var noises:Vector.<Number> = PerlinNoise.getNoise(100 /*<--x offset*/, 0, 100, 100, 6, 6, 1.0, 20);
Run Code Online (Sandbox Code Playgroud)

我尝试了几个选项,但不同的噪音部分没有停靠.

如果你有Perlin Noise的实现,它适用于世界发生器,你可以把它给我.

谢谢!

ric*_*son 2

Flash 已经通过该方法包含了 Perlin 噪声的实现BitmapData.perlinNoise()。如果您需要将噪声作为数字向量(而不是可渲染位图)获取,那么您可以使用将BitmapData.getVector()所有像素作为 32 位整数向量返回的方法,其中四个字节代表 alpha,分别为红色、绿色和蓝色通道。

我自己在一个项目中采用了这种模式,并取得了巨大的成功。下面是我编写和使用的函数。

public static function initNoiseVector(output : Vector.<Number>, baseX : Number, numOctaves : Number, scale : Number, blur : uint = 0) : void
{
    var i : uint;
    var len : uint;
    var sum : uint;
    var avg : uint;
    var perlin : BitmapData;
    var noise : Vector.<uint>;

    len = output.length;

    perlin = new BitmapData(len, 1);
    perlin.perlinNoise(baseX, 1, numOctaves, 0, true, false, 7, true);

    if (blur > 0)
        perlin.applyFilter(perlin, perlin.rect, new Point(), new BlurFilter(blur, 1, 3));

    noise = perlin.getVector(perlin.rect);

    // Calculate average
    sum = 0;
    for (i=0; i<len; i++) {
        // Mask out blue channel
        sum += noise[i]&0xff;
    }
    avg = sum/len;

    for (i=0; i<len; i++) {
        var speed : Number;

        // Convert perlin noise color to value between -1 and 1
        speed = ((noise[i]&0xff) - avg) / avg;
        output[i] = speed * scale;
    }
}
Run Code Online (Sandbox Code Playgroud)

该函数基本上只是创建一个 1px 高的位图(宽度定义为矢量的长度),在该位图中启动灰度 Perlin 噪声,可选择应用模糊,然后根据缩放函数参数缩放值。

缩放是通过首先计算平均值来完成的(仅使用蓝色通道,因为由于噪声是灰度,所以所有通道都是相同的。)然后将这些值在 -1 和 1 之间归一化,其中平均值为 0,并且按提供的比例因子缩放。

然后可以按以下方式使用该函数来检索 1000 个值:

_noise = new Vector.<Number>(1000, true);
PerlinNoiseUtil.initNoiseVector(_noise, 300, 10, randomDev * periodTime, 10);
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!