// ====== [GLOBAL VARIABLES] ====== let trail = []; let velocities = []; let particles = []; let flashAlpha = 0; let lastSliceTime = 0; let coconut = { x: 400, y: 300, r: 50 }; // ====== [SETUP] ====== function setup() { createCanvas(800, 600); } // ====== [DRAW LOOP] ====== function draw() { background(30); drawTrail(); drawCoconut(); checkSlice(); // ====== PARTICLES ====== for (let i = particles.length - 1; i >= 0; i--) { particles[i].update(); particles[i].draw(); if (particles[i].life <= 0) { particles.splice(i, 1); } } // ====== FLASH EFFECT ====== if (flashAlpha > 0) { fill(255, flashAlpha); rect(0, 0, width, height); flashAlpha -= 20; } } // ====== [INPUT: KNIFE TRACKING] ====== function mouseDragged() { let pos = createVector(mouseX, mouseY); trail.push(pos); if (trail.length > 1) { let v = p5.Vector.sub( trail[trail.length - 1], trail[trail.length - 2] ); velocities.push(v.mag()); } if (trail.length > 20) trail.shift(); if (velocities.length > 20) velocities.shift(); } // ====== [DRAW TRAIL] ====== function drawTrail() { noFill(); for (let i = 1; i < trail.length; i++) { let speed = velocities[i] || 0; let thickness = map(speed, 0, 50, 1, 10); strokeWeight(thickness); stroke(255, 200); line( trail[i - 1].x, trail[i - 1].y, trail[i].x, trail[i].y ); } } // ====== [DRAW COCONUT] ====== function drawCoconut() { fill(100, 255, 100); noStroke(); ellipse(coconut.x, coconut.y, coconut.r * 2); } // ====== [SLICE CHECK] ====== function checkSlice() { for (let i = 1; i < trail.length; i++) { let hit = lineCircle( trail[i - 1], trail[i], coconut.x, coconut.y, coconut.r ); if (hit && millis() - lastSliceTime > 100) { lastSliceTime = millis(); let speed = velocities[i] || 10; console.log("SLICE!"); spawnParticles(coconut.x, coconut.y, speed); flashAlpha = map(speed, 0, 50, 50, 150); } } } // ====== [COLLISION: LINE vs CIRCLE] ====== function lineCircle(p1, p2, cx, cy, r) { let ac = createVector(cx - p1.x, cy - p1.y); let ab = p5.Vector.sub(p2, p1); let ab2 = ab.magSq(); let acab = ac.dot(ab); let t = constrain(acab / ab2, 0, 1); let h = createVector( p1.x + ab.x * t, p1.y + ab.y * t ); let distSq = (h.x - cx) ** 2 + (h.y - cy) ** 2; return distSq <= r * r; } // ====== [PARTICLE CLASS] ====== class Particle { constructor(x, y, speed) { this.pos = createVector(x, y); this.vel = p5.Vector.random2D().mult(random(1, speed * 0.3)); this.life = 255; } update() { this.pos.add(this.vel); this.life -= 5; } draw() { noStroke(); fill(200, 255, 200, this.life); ellipse(this.pos.x, this.pos.y, 5); } } // ====== [SPAWN PARTICLES] ====== function spawnParticles(x, y, speed) { let count = map(speed, 0, 50, 5, 25); for (let i = 0; i < count; i++) { particles.push(new Particle(x, y, speed)); } }