2012-06-12 8 views
5

Uso il rumore Perlin per il generatore mondiale in 2D (come in Terraria). Ho trovato un'implementazione che mi si addice. Ho bisogno di generare parti del mondo, ma questa realizzazione può generare solo una volta il mondo intero.Come modificare il rumore Perlin [vedi esempio nella discussione]

Realizzazione - http://sirisian.com/javascriptgame/tests/valuenoise2.html ho riscritto per AS3, modificando leggermente (+ codice principale) - http://codepad.org/crMEQ2DD

Si prega di contribuire a modificare il codice in modo che fosse possibile generare una parte di rumore:

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

Ho provato diverse opzioni, ma le diverse parti del rumore non sono ancorate.

E se si dispone di un'implementazione di Perlin Noise, che è adatta per il generatore mondiale, è possibile darlo a me.

Grazie!

+0

Ciao, vedo che questa è una vecchia domanda .. Posso aiutarti ma non sono sicuro di capire completamente la domanda. C'è rumore perlin in Actionscript3: new BitmapData (width, height) .perlinNoise (..) – zehelvion

risposta

2

Flash contiene già un'implementazione del disturbo Perlin, tramite il metodo BitmapData.perlinNoise(). Quello che puoi fare se hai bisogno di ottenere il rumore come vettore di numeri (al contrario di una bitmap renderizzabile) è quello di utilizzare il metodo BitmapData.getVector() che restituisce tutti i pixel come un vettore di numeri interi a 32 bit, dove i quattro byte rappresentano alfa , rispettivamente, canali rossi, verdi e blu.

Ho utilizzato personalmente questo modello in un progetto, con grande successo. Di seguito è la stessa funzione che ho scritto e utilizzato.

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

Questa funzione fondamentalmente solo crea un'elevata bitmap 1px (larghezza definita come la lunghezza del vettore), avvia scala di grigi rumore Perlin dal fatto che bitmap, applica eventualmente una sfocatura e poi scale i valori secondo l'argomento della funzione scala .

La scalatura viene eseguita mediante il calcolo del valore medio (utilizzando solo il canale blu, poiché tutti i canali saranno identiche a causa del rumore essendo scala di grigi). I valori sono poi normalizzati tra -1 e 1, dove la media sarà essere 0, e ridimensionato dal fattore di scala fornito.

La funzione può quindi essere utilizzato nel modo seguente, per recuperare i valori 1000:

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

Spero che questo aiuti!