Random Walkers

For this week, we’re learning about random walkers. A fairly simple concept, although I wanted to brush up classes and methods, so I’m trying to convert the base code into something more modular so I can repeat it.

One reason for this is also because I wanted to combine it with today’s Genuary prompt, as I am making one generative sketch every day of January 2025.

Today’s prompt is - Grid-based graphic design.

So I’m aiming to lay out multiple walkers in a grid, and hopefully the class{} will help out with this structure.

A couple of references I looked at were - Class Random Walker by gracehlavacek and Random Walker Class by amygoodchild

Another thing I wanted to incorporate was a margin all around my canvas, so that the walkers in my grid don’t cross a certain threshold, giving a nice frame to my sketch. This turned out to take up more time than expected, and I ended up trying out various values for translating my canvas to the right location.

I set up a random step value (a choice between -1, 0, +1) for each square on my grid, and updated it’s x,y position based on this new value. I also applied a constrain to my x,y position so that it does not leave the bounds of each cell to maintain my margin frame.

Following is the output for a 10x10 grid -

RandomWalkerGrid_01.gif

let cols = 10
let rows = cols
let margin
let cellSize
let walkers = []

function setup() {
  createCanvas(windowWidth, windowWidth);
  margin = width / 4
  cellSize = (width - 2 * margin) / cols
  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      walkers.push(new Walker(i * cellSize, j * cellSize, cellSize))
    }
  }
}

function draw() {
  background(0, 20)
  translate(margin + cellSize/2, margin + cellSize/2)
  
  for (let walker of walkers) {
    walker.update();
  }
  
}

class Walker {
  constructor(x, y, size) {
    this.x = x
    this.y = y
    this.startX = x
    this.startY = y
    this.size = size
  }

  update() {
    
    let stepX = random([-1, 0, 1])
    let stepY = random([-1, 0, 1])
    
    this.x = constrain(this.x + stepX, this.startX - this.size, this.startX + this.size)
    this.y = constrain(this.y + stepY, this.startY - this.size, this.startY + this.size)

    fill('#fffff1')
    noStroke()
    square(this.x, this.y, this.size/10)
    
  }
  
}

The next thing I experimented with was my step increment (how far the square moves in a single frame), what if it was faster or slower, and what if it started slow and accelerated like a worm in agony?

To do this, I introduced a variable called stepSize and incremented it in my draw loop by 0.01, so it gets faster and faster as time goes on. Here’s how it looks -

RandomWalkerGrid_02.gif

This feels like a more interesting behaviour

I’ve underlined the code changes below