The Joy of the Random Walk
In this post, we’ll explore the beauty of "Random Walks" in creative coding. While the logic is remarkably simple, the visual results can be surprisingly sophisticated.
What is a Random Walk?
At its core, a random walk is incredibly simple. Here is the basic logic:
x += random(-1.0, 1.0); y += random(-1.0, 1.0);
That’s it! With just these two lines, you can create infinitely complex movement. 😀
Movement Variations
Constrained Randomness (Y-axis only)
By restricting randomness to only one axis, you can create organic, wire-like structures.
x += 1.0; y += random(-1.0, 1.0);
When applied to radial lines, the effect is even more striking:
The result looks like this:
Developing the idea further:
Perlin Noise
Using Perlin noise results in more fluid, organic motion—reminiscent of natural biological movement or elegant handwriting.
x += map(noise(a, t), 0.0, 1.0, -1.0, 1.0); y += map(noise(b, t), 0.0, 1.0, -1.0, 1.0); // a ≠ b : Some value for other noise seed. // t : time
Grid-based Movement
By snapping the walker's direction to the X or Y axis and matching the step size to the particle size, you can create a structured, "matrix-like" grid animation.
This example code was written in p5.js.
let direction = random(-1.0, 1.0);
direction = (direction == 0) ? 1.0 : direction / abs(direction);
if (random(1.0) < 0.5) {
x += direction * pSize;
} else {
y += direction * pSize;
}
// pSize : Walker size
Creative Stylization
Contrasting Colors
Something as simple as alternating between "ebony and ivory" (black and white) can drastically change the aesthetic. All it takes is adding the fill() function to the code above.
let direction = random(-1.0, 1.0);
direction = (direction == 0) ? 1.0 : direction / abs(direction);
if (random(1.0) < 0.5) {
x += direction * pSize;
fill(255);
} else {
y += direction * pSize;
fill(0);
}This example was implemented in p5.js on OpenProcessing.org. I added a residual image effect using a semi-transparent rectangle.
It will pause on a mouse click.
In 3D
ランダムウォーク・3Dのウォーカーをカメラが追随。— deconbatch (@deconbatch) January 11, 2020
動きが激しくて単にガクガクしてるようにしか見えない。😂#processing #creativecoding pic.twitter.com/lHNKoAtRjo
Draw Lines on the Walker Tail
— deconbatch (@deconbatch) January 20, 2020
Drawing with vertex()
Here, I used beginShape(TRIANGLES) to render the walker in various colors.
This is the example that draws curve lines using 'curveVertex()' and was implemented in p5.js on OpenProcessing.org. It will pause on a mouse click.
Oh... Poor walker getting lost...
Brilliant Works by Others
ランダムウォーク、パラメーター調整で遊ぶターン!— nasana (@nasana_x) January 14, 2020
配列によってサイズ変えてみたり、curveVertex使ってみたり。#p5js #processing #creativecoding #generativeart pic.twitter.com/A8FYh8iup3
— おかず (@okazz_) January 16, 2020
— FAL @STG制作&プログラミングお絵かき (@falworks_ja) January 14, 2020
The 'Processing' code examples.
Playing fake board game animation.
About this Example
A random walk example made with the 'Processing'. This creative coding creates a fake board game as a result of a random walk.
The 'Processing' code example of fake board game animation.
Please feel free to use it under the terms of the GPL.
It is my pleasure and honor to see other works based on my code.
Note: This code generates image files in the "frames" directory instead of displaying them on-screen. You can combine these frames to create a full animation.
/**
* It's A Game.
* A random walk animation. Guess which side is superior?
*
* Processing 3.5.3
* @author @deconbatch
* @version 0.1
* created 0.1 2020.02.05
*/
void setup() {
size(720, 440);
rectMode(CENTER);
smooth();
noLoop();
}
void draw() {
int frmMax = 5 * 30; // 5fps x 30s animation
int pLen = floor(width * 0.04);
int pSize = floor(width * 0.012);
ArrayList<path> paths = new ArrayList<Path>();
int pX = 0;
int pY = 0;
int pC = 0;
for(int frmCnt = 0; frmCnt < frmMax; frmCnt++) {
float direction = random(-1.0, 1.0);
direction = direction == 0 ? 1.0 : direction / abs(direction);
if (random(1.0) < 0.5) {
pX += direction * pLen;
pC = 255;
} else {
pY += direction * pLen;
pC = 0;
}
if (abs(pX) > width * 0.5) {
pX -= direction * pLen;
}
if (abs(pY) > height * 0.5) {
pY -= direction * pLen;
}
paths.add(new Path(pX, pY, pC));
}
translate(width * 0.5, height * 0.5);
for(int frmCnt = 0; frmCnt < frmMax; frmCnt++) {
background(240.0);
strokeWeight(1.0);
stroke(0);
beginShape(TRIANGLES);
for(int i = 0; i < frmCnt; i++) {
Path p = paths.get(i);
fill(p.colour);
vertex(p.x, p.y);
ellipse(p.x, p.y, pSize, pSize);
}
endShape();
casing();
saveFrame("frames/" + String.format("%04d", frmCnt) + ".png");
}
exit();
}
/**
* casing : draw fancy casing
*/
private void casing() {
fill(0.0, 0.0);
strokeWeight(20.0);
stroke(20.0);
rect(0.0, 0.0, width, height);
strokeWeight(15.0);
stroke(240.0);
rect(0.0, 0.0, width, height);
}
/**
* Path : hold random walk path
*/
private class Path {
public int x, y;
public int colour;
Path(int _x, int _y, int _c) {
x = _x;
y = _y;
colour = _c;
}
}
/*
Copyright (C) 2020- deconbatch
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
Walking on the grid animation.
About this creative coding example.
It's a creative coding work of random walk made with the 'Processing'. It walks on the triangular, quadrangular and hexagonal grid.
To render the walker's tail, I implemented a "shift" technique using an ArrayList. This allows the tail to follow the head dynamically as it moves.
Structure of walkers.
walkers(tails01(Walker0101, Walker0102..), tails02(Walker0201, Walker0202..)..)
Structure of tails.
← tail head →
tails01(Walker0101, Walker0102, .., Walker01nn)
↓ shift
tails01(Walker0102, Walker0103, .., Walker01nn + 1)
The 'Processing' code example of walking on the grid.
Please feel free to use it under the terms of the GPL.
To see other works based on my code is my pleasure. And my honor.
Note: This code generates image files in the "frames" directory instead of displaying them on-screen. You can combine these frames to create a full animation.
/**
* Saturday In The Park.
* A random walk on the grid.
*
* Processing 3.5.3
* @author @deconbatch
* @version 0.1
* created 0.1 2020.02.15
*/
void setup() {
size(720, 480);
colorMode(HSB, 360, 100, 100, 100);
rectMode(CENTER);
smooth();
noLoop();
}
void draw() {
int frmMax = 24 * 3; // 24fps * 3s animation with each pattern
int corners = 3; // initial pattern = 3 corners shape
translate(width * 0.5, height * 0.5);
for (int pattern = 0; pattern < 3; pattern++) {
corners += pattern; // 3, 4, 6
int walkerMax = 21 - pattern * 4;
int tailMax = corners * 3; // walker's tail
float sideLen = 8.0 - pattern * 2.0;
ArrayList walkers = new ArrayList();
for (int i = 0; i < walkerMax; i++) {
float wX = sideLen * corners * i - (sideLen * corners * walkerMax) * 0.5;
float wY = 0.0;
float wC = (50.0 * i) % 360.0;
float wD = TWO_PI / corners;
int wR = floor(random(corners));
ArrayList<Walker> tails = new ArrayList<Walker>();
for (int j = 0; j < tailMax; j++) {
tails.add(new Walker(wX, wY, wC, wD, wR));
}
walkers.add(tails);
}
for(int frmCnt = 0; frmCnt < frmMax; frmCnt++) {
background(0.0, 0.0, 100.0, 100.0);
strokeWeight(5.0);
noFill();
for (int i = 0; i < walkers.size(); i++) {
float wX = 0.0;
float wY = 0.0;
float wC = 0.0;
float wD = 0.0;
int wR = 0;
ArrayList<Walker> tails = (ArrayList)walkers.get(i);
for (Walker walker : tails) {
wX = walker.x;
wY = walker.y;
wC = walker.colour;
wD = walker.radianDiv;
wR = walker.rotateCnt;
stroke(wC, 40.0, 80.0, 100.0);
beginShape();
vertex(wX, wY);
for (int j = 0; j < corners; j++) {
// it makes a straight line between corners
wX += sideLen * cos(wR * wD);
wY += sideLen * sin(wR * wD);
vertex(wX, wY);
}
endShape();
}
if (abs(wX) < width * 0.35 && abs(wY) < height * 0.35) {
if (random(1.0) < 0.5) {
--wR; // not turn
} else {
if (random(1.0) < 0.1) {
wD *= -1.0; // turn
}
}
}
++wR;
wR %= corners;
// tail shift
tails.add(new Walker(wX, wY, wC, wD, wR));
tails.remove(0);
}
casing();
// for stop motion of first pattern
if (frmCnt == 0) {
for (int i = 0; i < 18; i++) {
saveFrame("frames/" + String.format("%02d", corners) + ".00." + String.format("%04d", i) + ".png");
}
}
saveFrame("frames/" + String.format("%02d", corners) + ".01." + String.format("%04d", frmCnt) + ".png");
}
}
exit();
}
/**
* casing : draw fancy casing
*/
private void casing() {
fill(0.0, 0.0, 0.0, 0.0);
strokeWeight(20.0);
stroke(0.0, 0.0, 0.0, 100.0);
rect(0.0, 0.0, width, height);
strokeWeight(15.0);
stroke(0.0, 0.0, 100.0, 100.0);
rect(0.0, 0.0, width, height);
}
/**
* Walker : hold random walker attributes
*/
private class Walker {
public float x, y;
public float colour;
public float radianDiv;
public int rotateCnt;
Walker(float _x, float _y, float _c, float _d, int _r) {
x = _x;
y = _y;
colour = _c;
radianDiv = _d;
rotateCnt = _r;
}
}
/*
Copyright (C) 2020- deconbatch
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/




















Really great article. Nice examples. I am sort of new to the processing system - we rebuilt something like it in ZIM at https://zimjs.com so I look forward to doing more relative drawing. I made some walking code without realizing that it was called walking ;-).
Thank you for your interest! I love your Zim cat. 🐱
Hi great article - in your example "This is the Random Walk" it always moves to 2 o'clock but you have -1,1 as the x and y ranges ??
Thank you for reading.
You can think 'It's just one example of examples'. It may go left side, up and down after this.
I realized this example is not the best. So I added some other examples.
I appreciate your comment. Thank you! 😉✨