Start: Loops + OOP

Use classes and arrays to manage many moving objects cleanly.

Example 1: Walker Class Array

Code

let walkers = [];

class Walker {
  constructor() {
    this.pos = createVector(random(width), random(height));
    this.vel = p5.Vector.random2D().mult(random(0.4, 2));
    this.r = random(4, 10);
  }
  update() {
    this.pos.add(this.vel);
    if (this.pos.x < 0 || this.pos.x > width) this.vel.x *= -1;
    if (this.pos.y < 0 || this.pos.y > height) this.vel.y *= -1;
  }
  draw() {
    circle(this.pos.x, this.pos.y, this.r * 2);
  }
}

function setup() {
  createCanvas(400, 400);
  for (let i = 0; i < 80; i++) walkers.push(new Walker());
  noStroke();
}

function draw() {
  background(249);
  fill(255, 55, 145, 170);
  for (let w of walkers) {
    w.update();
    w.draw();
  }
}

Try this: Increase the array size to 200 and test performance.

Open sketch in new tab

Example 2: Bubble Spawner

Code

let bubbles = [];

class Bubble {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = createVector(random(-1, 1), random(-2.5, -0.5));
    this.life = 255;
    this.r = random(8, 24);
  }
  update() {
    this.pos.add(this.vel);
    this.life -= 2;
  }
  draw() {
    noFill();
    stroke(255, 40, 130, this.life);
    circle(this.pos.x, this.pos.y, this.r * 2);
  }
  dead() {
    return this.life <= 0;
  }
}

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(255);
  bubbles.push(new Bubble(width / 2 + random(-20, 20), height - 20));
  for (let i = bubbles.length - 1; i >= 0; i--) {
    bubbles[i].update();
    bubbles[i].draw();
    if (bubbles[i].dead()) bubbles.splice(i, 1);
  }
}

Try this: Make bubbles shrink over time for a different look.

Open sketch in new tab

Resources