我在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);
我尝试了几个选项,但不同的噪音部分没有停靠。
如果你有Perlin Noise的实现,它适用于世界发生器,你可以把它给我。
谢谢!
答案 0 :(得分:2)
Flash已经通过BitmapData.perlinNoise()
方法包含了Perlin噪声的实现。如果你需要将噪声作为数字向量(而不是可渲染的位图),那么你可以做的是使用BitmapData.getVector()
方法将所有像素作为32位整数的向量返回,其中四个字节分别代表alpha,red,green和blue通道。
我自己在项目中采用了这种模式,取得了巨大的成功。以下是我编写和使用的函数。
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;
}
}
此函数基本上只创建1px高位图(宽度定义为矢量的长度),在该位图中启动灰度Perlin噪声,可选地应用模糊,然后根据比例函数参数缩放值。
通过首先计算平均值来完成缩放(仅使用蓝色通道,因为所有通道都是相同的,因为噪声是灰度级。)然后将值归一化在-1和1之间,其中平均值将是0,并按提供的比例因子缩放。
然后可以按以下方式使用该函数,以检索1000个值:
_noise = new Vector.<Number>(1000, true);
PerlinNoiseUtil.initNoiseVector(_noise, 300, 10, randomDev * periodTime, 10);
希望这有帮助!