xxxxxxxxxx
120
let sliders = {};
let walker;
function setup() {
createCanvas(600, 600, WEBGL);
colorMode(HSB, 100);
noStroke();
// Create sliders dynamically
const sliderData = [
{ label: 'Acceleration Range', min: 0, max: 0.5, value: 0.1, step: 0.01 },
{ label: 'Velocity Limit', min: 1, max: 10, value: 5, step: 0.1 },
{ label: 'Noise Scale', min: 0.001, max: 0.1, value: 0.01, step: 0.001 },
{ label: 'Trail Length', min: 50, max: 1000, value: 300, step: 10 },
{ label: 'Creature Size', min: 10, max: 100, value: 40, step: 1 }
];
let yPos = 10;
sliderData.forEach(data => {
createP(data.label).style('color', 'white').position(20, yPos);
sliders[data.label.split(' ')[0].toLowerCase()] = createSlider(data.min, data.max, data.value, data.step)
.position(20, yPos + 25)
.style('width', '100px');
yPos += 60;
});
walker = new Walker();
}
function draw() {
background(0);
orbitControl();
directionalLight(255, 255, 255, 1, 1, -1);
walker.update();
walker.display();
}
class Walker {
constructor() {
this.pos = createVector(0, 0, 0);
this.vel = createVector(0, 0, 0);
this.acc = createVector(0, 0, 0);
this.trail = [];
}
update() {
// Calculate acceleration using Perlin noise
const maxAcc = sliders.acceleration.value();
const noiseFactor = sliders.noise.value();
const t = frameCount * noiseFactor;
this.acc = createVector(
map(noise(t, 0), 0, 1, -maxAcc, maxAcc),
map(noise(t, 10), 0, 1, -maxAcc, maxAcc),
map(noise(t, 20), 0, 1, -maxAcc, maxAcc)
);
// Update velocity and limit it
this.vel.add(this.acc).limit(sliders.velocity.value());
this.pos.add(this.vel);
// Record current position into the trail
this.trail.push(this.pos.copy());
if (this.trail.length > sliders.trail.value()) this.trail.shift();
// Boundary wrap-around
const boundary = 400;
['x', 'y', 'z'].forEach(axis => {
if (this.pos[axis] > boundary) this.pos[axis] = -boundary;
if (this.pos[axis] < -boundary) this.pos[axis] = boundary;
});
}
display() {
push();
// Draw trail
this.trail.forEach((pos, i) => {
const hueVal = map(i, 0, this.trail.length, 50, 80);
const alphaVal = map(i, 0, this.trail.length, 10, 100);
emissiveMaterial(hueVal, 80, 80, alphaVal);
push();
translate(pos.x, pos.y, pos.z);
sphere(sliders.creature.value());
pop();
});
// Draw main creature
push();
translate(this.pos.x, this.pos.y, this.pos.z);
const creatureSize = sliders.creature.value();
// Central body with pulsating effect
push();
const pulse = sin(frameCount * 0.01) * creatureSize * 0.5;
ambientMaterial(200, 80, 80);
sphere(creatureSize + pulse);
pop();
// Rotating ring around the creature
push();
rotateY(frameCount * 0.05);
ambientMaterial(0, 80, 100);
torus(creatureSize * 5, creatureSize);
pop();
// Satellites orbiting the creature
const numSatellites = 4;
for (let i = 0; i < numSatellites; i++) {
push();
const angle = frameCount * 0.05 + i * TWO_PI / numSatellites;
translate(cos(angle) * creatureSize * 3, sin(angle) * creatureSize * 3, 0);
rotateY(frameCount * 0.01);
ambientMaterial(0, 0, 100);
sphere(creatureSize);
pop();
}
pop();
pop();
}
}