perlinField = new PerlinField(width, height);
noiseScale = createVector(0.025, 0.025);
velocity = createVector(0, 0);
wind = createVector(0, 0.01);
gui = QuickSettings.create(15, 15, "Perlin Navigators");
gui.addRange("Sprites Wanted", 0, 200, spritesWanted, 1, (value) => (spritesWanted = value));
gui.addRange("Sprite Wind", -0.2, 0.2, wind.x, 0.01, (value) => (wind.x = value));
gui.addRange("Noise Falloff ", 0, 2, falloff, 0.1, (value) => (falloff = value));
gui.addRange("Noise Octaves ", 0, 20, octaves, 1, (value) => (octaves = value));
gui.addRange("Noise Scale X", 0, 0.1, noiseScale.x, 0.001, (value) => (noiseScale.x = value));
gui.addRange("Noise Scale Y", 0, 0.1, noiseScale.x, 0.001, (value) => (noiseScale.y = value));
gui.addRange("Noise Velocity X", -0.2, 0.2, velocity.x, 0.01, (value) => (velocity.x = value));
gui.addRange("Noise Velocity Y", -0.2, 0.2, velocity.y, 0.01, (value) => (velocity.y = value));
while (sprites.length < spritesWanted) {
sprites.push(new Sprite());
perlinField.falloff = falloff;
perlinField.octaves = octaves;
perlinField.scale.set(noiseScale);
perlinField.velocity.set(velocity);
for (let i = sprites.length - 1; i >= 0; i--) {
this.acceleration = createVector(0, 0);
this.velocity = createVector(0, 0);
this.location = createVector(0, 0);
this.scale = createVector(0.025, 0.025);
this.canvas = createImage(this.w, this.h);
this.canvas.loadPixels();
for (let i = 0; i < this.canvas.pixels.length; i += 4) {
this.canvas.pixels[i + 3] = 255;
this.canvas.updatePixels();
this.tick = function () {
this.update = function () {
noiseDetail(octaves, falloff);
this.velocity.add(this.acceleration);
this.location.add(this.velocity);
this.render = function () {
for (let x = 0; x < this.w; x++) {
for (let y = 0; y < this.h; y++) {
let pixelIndex = y * this.w * 4 + x * 4;
let c = this.getNoiseValue(x, y) * 255;
this.canvas.pixels[pixelIndex] = c;
this.canvas.pixels[pixelIndex + 1] = c;
this.canvas.pixels[pixelIndex + 2] = c;
this.canvas.updatePixels();
image(this.canvas, 0, 0);
this.getNoiseValue = function (x, y) {
return noise(x * this.scale.x + this.location.x, y * this.scale.y + this.location.y);
this.acceleration = createVector(0, 0);
this.velocity = createVector(0, 0);
this.location = createVector(random(width), 10);
this.tick = function () {
this.update = function () {
this.velocity.add(this.acceleration);
this.velocity.add(this.gravity);
this.location.add(this.velocity);
let perlin = perlinField.getNoiseValue(this.location.x, this.location.y);
let steering = createVector(map(perlin, 0, 1, -0.02, 0.02), 0);
let friction = createVector(0, map(perlin, 0, 1, -0.05, 0.05));
this.acceleration.add(steering);
this.acceleration.add(friction);
if (this.acceleration.y < 0) {
this.acceleration.limit(0.1);
this.checkEdges = function () {
if (this.location.y < 0 || this.location.y > height || this.location.x < 0 || this.location.x > width) {
this.render = function () {
this.drawVector(this.velocity, this.location, 10);
this.drawVector = function (v, loc, scale) {
let len = v.mag() * scale;
line(len, 0, len - arrowsize, +arrowsize / 2);
line(len, 0, len - arrowsize, -arrowsize / 2);