xxxxxxxxxx
205
let molds = [];
let agent;
let d;
let showUI = false;
let textLines = [];
const MAX_CHARS = 5;
const LINE_COUNT = 5;
// Control variables
let params = {
particleSize: 1,
particleSpeed: 1.0,
trailIntensity: 10,
sensorDistance: 10,
sensorAngle: 45,
rotationAngle: 45,
maxParticles: 2000,
emissionRate: 2,
agentSpeed: 3
};
class Agent {
constructor(x, y) {
this.x = x;
this.y = y;
this.angle = 0;
this.emitCounter = 0;
}
update() {
let dx = mouseX - this.x;
let dy = mouseY - this.y;
let targetAngle = atan2(dy, dx);
let currentAngle = radians(this.angle);
let angleDiff = targetAngle - currentAngle;
if (angleDiff > PI) angleDiff -= TWO_PI;
if (angleDiff < -PI) angleDiff += TWO_PI;
this.angle += degrees(angleDiff * 0.1);
this.x += cos(radians(this.angle)) * params.agentSpeed;
this.y += sin(radians(this.angle)) * params.agentSpeed;
this.emitCounter++;
if (this.emitCounter >= params.emissionRate) {
this.emitCounter = 0;
this.emit();
}
}
emit() {
if (molds.length >= params.maxParticles) {
molds.shift();
}
molds.push(new Mold(this.x, this.y));
}
display() {
push();
noStroke();
fill(100, 100, 255);
translate(this.x, this.y);
rotate(radians(this.angle));
pop();
}
}
class Mold {
constructor(x, y) {
this.x = x;
this.y = y;
this.heading = random(360);
this.vx = cos(this.heading);
this.vy = sin(this.heading);
// Assign color based on total number of particles
let colorIndex = molds.length % 3;
if (colorIndex === 0) {
this.color = color(0, 255, 255, 77); // Cyan
} else if (colorIndex === 1) {
this.color = color(255, 0, 255, 77); // Magenta
} else {
this.color = color(255, 255, 0, 77); // Yellow
}
}
update() {
this.rSensorPos = createVector(
(this.x + params.sensorDistance * cos(this.heading + params.sensorAngle) + width) % width,
(this.y + params.sensorDistance * sin(this.heading + params.sensorAngle) + height) % height
);
this.lSensorPos = createVector(
(this.x + params.sensorDistance * cos(this.heading - params.sensorAngle) + width) % width,
(this.y + params.sensorDistance * sin(this.heading - params.sensorAngle) + height) % height
);
this.fSensorPos = createVector(
(this.x + params.sensorDistance * cos(this.heading) + width) % width,
(this.y + params.sensorDistance * sin(this.heading) + height) % height
);
let index, l, r, f;
index = 4 * (d * floor(this.rSensorPos.y)) * (d * width) + 4 * (d * floor(this.rSensorPos.x));
r = pixels[index];
index = 4 * (d * floor(this.lSensorPos.y)) * (d * width) + 4 * (d * floor(this.lSensorPos.x));
l = pixels[index];
index = 4 * (d * floor(this.fSensorPos.y)) * (d * width) + 4 * (d * floor(this.fSensorPos.x));
f = pixels[index];
if (f > l && f > r) {
this.heading += 0;
} else if (f < l && f < r) {
if (random(1) < 0.5) {
this.heading += params.rotationAngle;
} else {
this.heading -= params.rotationAngle;
}
} else if (l > r) {
this.heading += -params.rotationAngle;
} else if (r > l) {
this.heading += params.rotationAngle;
}
this.vx = cos(this.heading) * params.particleSpeed;
this.vy = sin(this.heading) * params.particleSpeed;
this.x = (this.x + this.vx + width) % width;
this.y = (this.y + this.vy + height) % height;
}
display() {
noStroke();
blendMode(ADD);
fill(this.color);
ellipse(this.x, this.y, params.particleSize * 2, params.particleSize * 2);
blendMode(BLEND);
}
}
function setup() {
createCanvas(405, 720);
angleMode(DEGREES);
d = pixelDensity();
agent = new Agent(width/2, height/2);
textSize(30);
textAlign(CENTER, CENTER);
// Initialize text lines with fixed positions
let yPositions = [120, 240, 360, 480, 600];
for(let i = 0; i < LINE_COUNT; i++) {
textLines.push({
pos: createVector(width/2, yPositions[i]),
buffer: []
});
}
}
function draw() {
background(0, params.trailIntensity);
loadPixels();
agent.update();
for (let mold of molds) {
mold.update();
mold.display();
}
agent.display();
// Display text lines
fill(255);
noStroke();
textLines.forEach(line => {
text(line.buffer.join(''), line.pos.x, line.pos.y);
});
}
function keyPressed() {
if (key === 'h' || key === 'H') {
showUI = !showUI;
return;
}
if (key.length === 1 && /[a-zA-Z\s]/.test(key)) {
const newChar = key.toUpperCase();
if (textLines[0].buffer.length < MAX_CHARS) {
textLines[0].buffer.push(newChar);
} else {
let overflowChar = textLines[0].buffer.shift();
textLines[0].buffer.push(newChar);
for (let i = 1; i < textLines.length; i++) {
if (textLines[i].buffer.length < MAX_CHARS) {
textLines[i].buffer.push(overflowChar);
break;
} else {
const nextOverflow = textLines[i].buffer.shift();
textLines[i].buffer.push(overflowChar);
overflowChar = nextOverflow;
}
}
}
}
}