用代码描述自然系统-简单粒子系统01
前面的文章中实现了基本力,并模拟了物体的基本运动规律,本篇博文将基于前面的文章,构建一个简单的粒子系统。
粒子系统
粒子系统在很多领域都有大量应用,小到游戏开发,大到宇宙模拟,本质上都是对最小粒子的模拟,所以实现简单的例子系统非常有用。
本篇博文实现一个简单的系统,初始世界中会随机生成一定数量的粒子,这些粒子满足几点规则:
- 粒子距离大于 100 时,粒子之间表现为引力;
- 粒子距离小于 100 时,粒子之间表现为斥力;
- 整个粒子系统会施加一定的阻力,阻碍粒子的运动;
基于以上规则,实现粒子系统,最终的静止效果如下图所示:
代码实现
有了之前的博文打基础,这个示例实现起来比较简单,就不一一解释了,直接贴代码:
const PWidth = 800, PHeight = 500;
const count = 100;
const radius = 160;
const balls = [];
class Ball {
constructor(mass) {
this.mass = mass;
this.position = createVector(random(PWidth), random(PHeight));
this.velocity = createVector(0, 0);
this.color = color(random(180, 255), random(100, 200));
}
setColor(color) {
this.color = color;
}
setPosition(position) {
this.position = position;
}
addFore(f) {
this.velocity.add(f);
}
update() {
this.position.add(this.velocity);
}
display() {
fill(this.color);
noStroke();
ellipse(this.position.x, this.position.y, this.mass * 200);
}
}
function setup() {
createCanvas(PWidth, PHeight);
for (let i = 0; i < count; i++) {
const ball = new Ball(random(0.02, 0.1));
ball.setColor(color(255, 255, 18, random(100, 255)));
balls.push(ball);
}
}
function draw() {
background(10);
balls.forEach(ball => {
const f = ball.velocity.copy().normalize().mult(-0.15 * ball.velocity.mag());
balls.forEach(op => {
if (ball === op) return;
const dist = p5.Vector.dist(op.position, ball.position);
const force = p5.Vector.sub(op.position, ball.position).normalize().mult((dist - radius) * ball.mass / radius);
ball.addFore(force);
});
ball.addFore(f);
ball.update();
ball.display();
});
}
function mouseClicked() {
balls[parseInt(random(count))].addFore(p5.Vector.random2D().mult(random(20, 50)));
}
运行效果如下:
单击鼠标左键,可以增加随机扰动。
可以 点击这里 打开新窗口查看效果。
亦或是随机颜色的效果:
可以 点击这里 打开新窗口查看效果。