?向 豆包 提問:編寫一個 p5.js 腳本,模擬 42 個彩色小球在一個3D大球體內部彈跳。每個小球都應留下一條逐漸消失的軌跡。大球體應緩慢旋轉,并顯示透明的輪廓線。請確保實現適當的碰撞檢測,使小球保持在球體內部。
cd p5-demo
copy .\node_modules\p5\lib\p5.min.js .
編寫? p5_3d_42_balls.html? 如下
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>3D Bouncing Balls in Sphere</title><script src="p5.min.js"></script>
</head><body>
<script>let balls = [];let sphereRadius = 200;let rotationSpeed = 0.01;function setup() {createCanvas(800, 600, WEBGL);for (let i = 0; i < 42; i++) {balls.push(new Ball());}}function draw() {background(0);rotateX(frameCount * rotationSpeed);rotateY(frameCount * rotationSpeed);// 繪制大球體stroke(255, 100);noFill();sphere(sphereRadius);// 更新并繪制小球for (let ball of balls) {ball.update();ball.display();}}class Ball {constructor() {this.pos = p5.Vector.random3D().mult(random(0, sphereRadius));this.vel = p5.Vector.random3D().mult(random(1, 3));this.color = color(random(255), random(255), random(255));this.trail = [];this.trailLength = 20;}update() {this.pos.add(this.vel);// 碰撞檢測let distanceToCenter = this.pos.mag();if (distanceToCenter > sphereRadius) {let normal = this.pos.copy().normalize();this.vel.reflect(normal);// 確保小球回到球體內this.pos = normal.mult(sphereRadius - 0.1); }// 更新軌跡this.trail.push(this.pos.copy());if (this.trail.length > this.trailLength) {this.trail.shift();}}display() {// 繪制軌跡for (let i = 0; i < this.trail.length; i++) {let alpha = map(i, 0, this.trail.length, 255, 0);stroke(this.color.levels[0], this.color.levels[1], this.color.levels[2], alpha);if (i > 0) {line(this.trail[i - 1].x, this.trail[i - 1].y, this.trail[i - 1].z, this.trail[i].x, this.trail[i].y, this.trail[i].z);}}// 繪制小球fill(this.color);noStroke();push();translate(this.pos.x, this.pos.y, this.pos.z);sphere(5);pop();}}
</script>
</body>
</html>
雙擊打開 p5_3d_42_balls.html?
交互式分形樹
-
描述: 創建一個分形樹,用戶可以通過鼠標或鍵盤控制樹的生長角度、分支長度等參數。
-
編寫 p5_branch.html? 如下
-
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>p5 branch Example</title><script src="p5.min.js"></script> </head> <body> <script> // 創建分形樹,用戶可以通過鼠標控制樹的生長角度、分支長度等參數。function setup() {createCanvas(800, 600);angleMode(DEGREES);}function draw() {background(50);stroke(255);translate(width/2, height);branch(map(mouseX, 0, width, 50, 150));}function branch(len) {line(0, 0, 0, -len);translate(0, -len);if (len > 4) {push();rotate(map(mouseY, 0, height, 20, 60));branch(len * 0.67);pop();push();rotate(-map(mouseY, 0, height, 20, 60));branch(len * 0.67);pop();}} </script> </body> </html>
雙擊打開?p5_branch.html?
動態波形生成器
-
描述: 創建一個動態波形,用戶可以通過鼠標或鍵盤控制波形的頻率、振幅或顏色。
-
編寫 p5_wave.html? 如下
-
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>p5 wave Example</title><script src="p5.min.js"></script> </head> <body> <script>let angle = 0;let amplitude = 100;let frequency = 0.02;function setup() {createCanvas(windowWidth, windowHeight);}function draw() {background(0);noFill();stroke(255);strokeWeight(2);beginShape();for (let x = 0; x < width; x += 10) {let y = height / 2 + sin(angle + x * frequency) * amplitude;vertex(x, y);}endShape();angle += 0.05;}function mouseMoved() {amplitude = map(mouseY, 0, height, 50, 200);frequency = map(mouseX, 0, width, 0.01, 0.1);} </script> </body> </html>
雙擊打開?p5_wave.html?