p5.js system
Analog Algorithm
A rule-based drawing where dice values control line length, direction and repetition.
View full p5.js code
let numPlayers = 4;
let maxCycles = 5;
let stepSize = 32;
let players = [];
let totalRestarts = 0;
let maxRestarts = 5;
let isWaiting = false;
let waitStartTime = 0;
let restartButton;
function setup() {
const canvas = createCanvas(600, 600);
canvas.parent('sketchHolder');
restartButton = select('#restartSketch');
if (restartButton) {
restartButton.mousePressed(() => {
totalRestarts = 0;
loop();
initDrawing();
});
}
initDrawing();
}
function initDrawing() {
background(220);
stroke(0);
strokeWeight(2);
players = [];
isWaiting = false;
let centerX = width / 2;
let centerY = height / 2;
let offset = 70;
let startPositions = [
{ x: centerX - offset, y: centerY - offset },
{ x: centerX + offset, y: centerY - offset },
{ x: centerX + offset, y: centerY + offset },
{ x: centerX - offset, y: centerY + offset }
];
for (let i = 0; i < numPlayers; i++) {
players.push({
startX: startPositions[i].x,
startY: startPositions[i].y,
x: startPositions[i].x,
y: startPositions[i].y,
currentStep: 0,
currentCycle: 0,
delay: i * 5,
finished: false
});
}
}
function draw() {
if (!isWaiting) {
for (let p of players) {
if (!p.finished && frameCount > p.delay && frameCount % 6 === 0) {
let dice = floor(random(1, 7));
let dist = dice * stepSize;
let prevX = p.x;
let prevY = p.y;
if (p.currentStep === 0) p.y -= dist;
else if (p.currentStep === 1) p.x += dist;
else if (p.currentStep === 2) p.y += dist;
else if (p.currentStep === 3) p.x -= dist;
p.x = constrain(p.x, 0, width);
p.y = constrain(p.y, 0, height);
line(prevX, prevY, p.x, p.y);
p.currentStep++;
if (p.currentStep > 3) {
p.currentStep = 0;
p.currentCycle++;
p.x = p.startX;
p.y = p.startY;
if (p.currentCycle >= maxCycles) p.finished = true;
}
}
}
if (players.every(p => p.finished)) {
isWaiting = true;
waitStartTime = millis();
totalRestarts++;
}
} else {
if (totalRestarts < maxRestarts) {
if (millis() - waitStartTime > 5000) {
initDrawing();
}
} else {
noLoop();
}
}
}