River Flow

Click the link or highlight the code and copy it.  

Then, go to p5js.org and paste the code in the editor. 

Hit the "run" button, watch what happens. 

Make adjustments to the code, the hit the "run" button again. 

Repeat.  :) 

LINK TO WORKING CODE 


let riverWidth = 600; // Width of the river

let riverHeight = 400; // Height of the river


let numParticles = 200; // Number of water particles

let particles = []; // Array to store water particles


function setup() {

  createCanvas(800, 600);

  

  // Create water particles

  for (let i = 0; i < numParticles; i++) {

    let x = random(width);

    let y = random(height);

    let particle = new Particle(x, y);

    particles.push(particle);

  }

}


function draw() {

  background(220);

  

  // Draw the river

  fill(150, 200, 255); // Light blue color

  rect((width - riverWidth) / 2, (height - riverHeight) / 2, riverWidth, riverHeight);

  

  // Update and display water particles

  for (let i = 0; i < particles.length; i++) {

    let particle = particles[i];

    particle.update();

    particle.display();

  }

}


class Particle {

  constructor(x, y) {

    this.position = createVector(x, y);

    this.velocity = createVector(0, 0);

    this.acceleration = createVector(0, 0);

    this.maxSpeed = 2;

  }

  

  update() {

    // Apply forces to the particle

    let flowForce = this.calculateFlowForce();

    this.applyForce(flowForce);

    

    // Update velocity and position

    this.velocity.add(this.acceleration);

    this.velocity.limit(this.maxSpeed);

    this.position.add(this.velocity);

    

    // Reset acceleration

    this.acceleration.mult(0);

    

    // Check if particle is out of bounds

    if (this.position.x < 0 || this.position.x > width || this.position.y < 0 || this.position.y > height) {

      this.position.x = random(width);

      this.position.y = random(height);

    }

  }

  

  calculateFlowForce() {

    // Calculate the flow force based on the position in the river

    let riverCenterX = width / 2;

    let riverCenterY = height / 2;

    

    let targetX = riverCenterX + map(this.position.y, 0, height, -riverWidth / 2, riverWidth / 2);

    let targetY = this.position.y;

    

    let desiredVelocity = createVector(targetX, targetY).sub(this.position);

    desiredVelocity.setMag(this.maxSpeed);

    

    let steerForce = desiredVelocity.sub(this.velocity);

    steerForce.limit(0.1);

    

    return steerForce;

  }

  

  applyForce(force) {

    // Apply force to the particle

    this.acceleration.add(force);

  }

  

  display() {

    // Display the particle

    fill(0, 100, 255); // Dark blue color

    ellipse(this.position.x, this.position.y, 5, 5);

  }

}