
import controlP5.*;
ControlP5 controlP5;
PerlinField perlinField;
ArrayList sprites;
public float falloff = .5;
public int octaves = 5;
public float noiseScaleX = 0.05;
public float noiseScaleY = 0.05;
public float accelerationX;
public float accelerationY;
public int spritesWanted = 10;
PVector gravity;
PVector wind;
void setup() {
size(564, 564);
background(0);
smooth();
gravity = new PVector(0, 0.01);
wind = new PVector(0, 0);
perlinField = new PerlinField(width, height, this);
controlP5 = new ControlP5(this);
Slider spritesWantedlider = controlP5.addSlider("spritesWanted", 0, 100, spritesWanted, 300, height - 80, 130, 10);
Slider falloffSlider = controlP5.addSlider("falloff", 0, 2, falloff, 300, height - 65, 130, 10);
Slider octavesSlider = controlP5.addSlider("octaves", 0, 20, octaves, 300, height - 50, 130, 10);
Slider noiseScaleXSlider = controlP5.addSlider("noiseScaleX", 0, .1, noiseScaleX, 300, height - 35, 130, 10);
Slider noiseScaleYSlider = controlP5.addSlider("noiseScaleY", 0, .1, noiseScaleY, 300, height - 20, 130, 10);
Slider accelerationXSlider = controlP5.addSlider("accelerationX", -.1, .1, 0, 100, height - 35, 130, 10);
Slider accelerationYSlider = controlP5.addSlider("accelerationY", -.1, .1, 0, 100, height - 20, 130, 10);
sprites = new ArrayList();
}
void draw() {
background(0);
// Maintain the sprite population.
while (sprites.size() < spritesWanted) {
sprites.add(new Sprite());
}
// update perlin field settings from the sliders
perlinField.falloff = falloff;
perlinField.octaves = octaves;
perlinField.acceleration.x = accelerationX;
perlinField.acceleration.y = accelerationY;
perlinField.scale.x = noiseScaleX;
perlinField.scale.y = noiseScaleY;
perlinField.tick();
// use perlin as frictoin
for (int i = sprites.size() - 1; i >= 0; i--) {
Sprite sprite = (Sprite) sprites.get(i);
sprite.tick();
// Clean up the dead.
if(sprite.killMe) {
sprites.remove(i);
}
}
}
// Wanted to make this a subclass of PGraphics, but had instantation problems
// despite following recommendations at
// http://dev.processing.org/reference/core/javadoc/processing/core/PGraphics
class PerlinField {
int w;
int h;
PApplet parent;
PVector acceleration;
PVector velocity;
PVector location;
PVector scale;
public int octaves;
public float falloff;
PImage canvas;
PerlinField(int _w, int _h, PApplet _parent) {
println("perlin field constructor");
parent = _parent;
w = _w;
h = _h;
canvas = createImage(w, h, RGB);
acceleration = new PVector(0, 0);
velocity = new PVector(0, 0);
location = new PVector(0, 0);
scale = new PVector(.05, .05);
println(getNoiseValue(3, 3));
println(scale.x);
}
void tick() {
update();
render();
}
void update() {
// set the velocity
velocity.add(acceleration);
location.add(velocity);
}
void render() {
canvas.loadPixels();
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
canvas.pixels[(y * w) + x] = color(getNoiseValue(x, y) * 255);
}
}
canvas.updatePixels();
parent.image(canvas, 0, 0);
}
float getNoiseValue(int x, int y) {
noiseDetail(octaves, falloff);
return noise( ((float)x * scale.x) + location.x, ((float)y * scale.y) + location.y);
}
}
class Sprite {
boolean showArrow = true;
PVector acceleration;
PVector velocity;
PVector location;
boolean killMe = false;
Sprite() {
println("sprite constructor");
acceleration = new PVector(0, 0);
velocity = new PVector(0, 0);
location = new PVector(random(width), 10);
}
void tick() {
update();
checkEdges();
render();
}
void update() {
velocity.add(acceleration);
velocity.add(gravity);
velocity.add(wind);
location.add(velocity);
float perlin = perlinField.getNoiseValue((int)location.x, (int)location.y);
PVector steering = new PVector(map(perlin , 0, 1, -.02, .02), 0);
PVector friction = new PVector(0, map(perlin , 0, 1, -.05, .05));
acceleration.add(steering);
acceleration.add(friction);
// don't let them go up
if(acceleration.y < 0) acceleration.y = 0;
acceleration.limit(.05);
velocity.limit(5);
}
void checkEdges() {
if (location.y > height) {
// mark for deletion
killMe = true;
}
}
void render() {
// fill(255);
// rect(location.x, location.y, 20, 20);
if(showArrow) {
drawVector(velocity, location, 10);
}
}
}
// Renders a vector object 'v' as an arrow and a location 'loc'
// From Dan Shiffman's example
void drawVector(PVector v, PVector loc, float scale) {
pushMatrix();
float arrowsize = 12;
// Translate to location to render vector
translate(loc.x,loc.y);
stroke(255);
strokeWeight(2);
// Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate
rotate(v.heading2D());
// Calculate length of vector & scale it to be bigger or smaller if necessary
float len = v.mag()*scale;
// Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction)
line(0,0,len,0);
line(len,0,len-arrowsize,+arrowsize/2);
line(len,0,len-arrowsize,-arrowsize/2);
popMatrix();
}
OpenProcessing is an online community platform devoted to sharing and discussing Processing sketches in a collaborative, open-source environment.
Download Processing
Terms of Service
To contact, send an email to:

See the feedback forum and vote!
Follow OpenProcessing on Twitter.
All sketches are licensed under Creative Commons Attribution-Share Alike 3.0.
Syntax highlighting and Processing brush under LGPL 3.
All the source code is licensed under Creative Commons GNU GPL.
Comments engine by Scriptsmill Comments Script.
