104 lines, no comments ยท 4,073 tokens, written in 37 seconds for $0.041


  1  let particles = [];
  2  let scale = 10;
  3  let cols, rows;
  4  let zoff = 0;
  5  let flowfield;
  6  
  7  function setup() {
  8    createCanvas(600, 400);
  9    cols = floor(width / scale);
 10    rows = floor(height / scale);
 11    flowfield = new Array(cols * rows);
 12  
 13    for (let i = 0; i < 500; i++) {
 14      particles[i] = new Particle();
 15    }
 16    background(0);
 17    colorMode(HSB, 360, 100, 100, 1);
 18  }
 19  
 20  function draw() {
 21    let yoff = 0;
 22    for (let y = 0; y < rows; y++) {
 23      let xoff = 0;
 24      for (let x = 0; x < cols; x++) {
 25        let index = x + y * cols;
 26        let angle = noise(xoff, yoff, zoff) * TWO_PI * 4;
 27        let v = p5.Vector.fromAngle(angle);
 28        v.setMag(1);
 29        flowfield[index] = v;
 30        xoff += 0.1;
 31      }
 32      yoff += 0.1;
 33    }
 34    zoff += 0.005;
 35  
 36    for (let i = 0; i < particles.length; i++) {
 37      particles[i].follow(flowfield);
 38      particles[i].update();
 39      particles[i].edges();
 40      particles[i].show();
 41    }
 42  }
 43  
 44  class Particle {
 45    constructor() {
 46      this.pos = createVector(random(width), random(height));
 47      this.vel = createVector(0, 0);
 48      this.acc = createVector(0, 0);
 49      this.maxspeed = 4;
 50      this.prevPos = this.pos.copy();
 51      this.h = random(360);
 52    }
 53  
 54    update() {
 55      this.vel.add(this.acc);
 56      this.vel.limit(this.maxspeed);
 57      this.pos.add(this.vel);
 58      this.acc.mult(0);
 59    }
 60  
 61    follow(vectors) {
 62      let x = floor(this.pos.x / scale);
 63      let y = floor(this.pos.y / scale);
 64      let index = x + y * cols;
 65      let force = vectors[index];
 66      this.applyForce(force);
 67    }
 68  
 69    applyForce(force) {
 70      this.acc.add(force);
 71    }
 72  
 73    show() {
 74      stroke(this.h, 90, 90, 0.1);
 75      this.h = (this.h + 0.5) % 360;
 76      strokeWeight(1);
 77      line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
 78      this.updatePrev();
 79    }
 80    
 81    updatePrev() {
 82      this.prevPos.x = this.pos.x;
 83      this.prevPos.y = this.pos.y;
 84    }
 85  
 86    edges() {
 87      if (this.pos.x > width) {
 88        this.pos.x = 0;
 89        this.updatePrev();
 90      }
 91      if (this.pos.x < 0) {
 92        this.pos.x = width;
 93        this.updatePrev();
 94      }
 95      if (this.pos.y > height) {
 96        this.pos.y = 0;
 97        this.updatePrev();
 98      }
 99      if (this.pos.y < 0) {
100        this.pos.y = height;
101        this.updatePrev();
102      }
103    }
104  }