2012-06-12 6 views
5

Używam Perlin Noise do generatora świata w 2D (jak w Terraria). Znalazłem implementację, która mi odpowiada. Potrzebuję generować części świata, ale ta realizacja może tylko raz wygenerować cały świat.Jak zmodyfikować szum Perlina [zobacz przykład w wątku]

Realizacja - http://sirisian.com/javascriptgame/tests/valuenoise2.html I przepisał go do AS3, nieznacznie modyfikując (+ główny kod) - http://codepad.org/crMEQ2DD

Proszę pomóc zmodyfikować kod tak, aby możliwe było wygenerowanie część szumu:

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); 

Próbowałem kilka opcji, ale różne części szumu nie są zadokowane.

Jeśli masz implementację szumu Perlin, który jest odpowiedni dla generatora światowego, możesz mi go przekazać.

Dzięki!

+0

Witam, widzę, że to stare pytanie. Mogę pomóc, ale nie jestem pewien, czy całkowicie rozumiem to pytanie. W Actionscript3 występuje szum perlinowy: nowa bitmapData (szerokość, wysokość) .perlinNoise (..) – zehelvion

Odpowiedz

2

Flash zawiera już implementację szumu Perlin, za pomocą metody BitmapData.perlinNoise(). Co możesz zrobić, jeśli chcesz uzyskać szum jako wektor liczb (w przeciwieństwie do możliwej do renderowania bitmapy), to użyj metody BitmapData.getVector(), która zwraca wszystkie piksele jako wektor 32-bitowych liczb całkowitych, gdzie cztery bajty reprezentują alfa , odpowiednio czerwone, zielone i niebieskie kanały.

Sam ten wzór wykorzystałem w projekcie, do wielkiego sukcesu. Poniżej znajduje się funkcja, którą napisałem i wykorzystałem.

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; 
    } 
} 

Funkcja zasadzie tylko tworzy 1px wysoką mapę bitową (szerokość definiowana jako długość wektora), inicjuje szarości hałasu Perlin w tej mapy bitowej, ewentualnie stosuje rozmazanie i skaluje wartości w zależności od funkcji argumentu skalę .

Skalowanie odbywa się poprzez obliczenie wartości średniej (używając tylko kanału niebieskiego, ponieważ wszystkie kanały będą identyczne ze względu na szumy będące w skali szarości). Wartości są następnie normalizowane między -1 i 1, gdzie średnia wartość 0 i skalowane przez dostarczony współczynnik skalowania.

Funkcja ta może być następnie wykorzystana w następujący sposób, aby odzyskać 1000 wartości:

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

Nadzieja to pomaga!