|

用代码描述自然系统-简单粒子系统02

在前两年 H5 开始流行的时候,网上出现了许多看起来很炫酷的粒子动画效果,其中就包含了很多简单的粒子系统,本篇将基于前几篇文章的基础,实现这些看起来炫酷的效果。

构造粒子类

所有的粒子系统都必须基于一个基本的粒子类来实现,借助向量实现对粒子的物理模拟。在前面的几篇文章中,我们构建最多的就是 Mover 类,本篇我们将实现一个 Particle 类。

Particle 类与之前的 Mover 类功能大体类似,下面直接实现 Particle 类。

class Particle {
  constructor(mass) {
    this.mass = mass;
    this.diameter = this.mass * 1;
    this.position = createVector(random(PWidth), random(PHeight));
    this.velocity = createVector(random(-0.5, 0.5), random(-0.5, 0.5));
    this.color = color(random(100, 200), 100);
  }

  setColor(color) {
    this.color = color;
  }

  setPosition(position) {
    this.position = position;
  }

  setVelocity(vel) {
    this.velocity = vel;
  }

  addFore(f) {
    this.velocity.add(f);
  }

  update() {
    this.position.add(this.velocity);
    const r = this.diameter / 2;
    if (this.position.x - r <= 0) {
      this.position.x = r;
      this.velocity.x *= -1;
    }
    if (this.position.x + r >= PWidth) {
      this.position.x = PWidth - r;
      this.velocity.x *= -1;
    }
    if (this.position.y - r <= 0) {
      this.position.y = r;
      this.velocity.y *= -1;
    }
    if (this.position.y + r >= PHeight) {
      this.position.y = PHeight - r;
      this.velocity.y *= -1;
    }
  }

  display() {
    fill(this.color);
    noStroke();
    ellipse(this.position.x, this.position.y, this.diameter);
  }
}

定义规则-1

构建粒子系统另一个重要因素就是规则定义,我们即将要实现的粒子系统需要满足下面的规则:

  • 粒子之间的距离大于 100 时不做处理;
  • 粒子之间的距离小于 100 时,在满足距离条件的例子之间连线;
  • 粒子之间的连线透明度随距离的减小而减小,即距离越大透明度越高,距离越小透明度越小;

基于以上的规则,实现 draw 函数如下:

function draw() {
  background(10);
  particles.forEach(particle => {
    particles.forEach(op => {
      if (particle === op) return;
      const dist = p5.Vector.dist(particle.position, op.position);
      if (dist > radius) return;
      stroke(200, (1 - dist / radius) * 100);
      strokeWeight(1);
      line(particle.position.x, particle.position.y, op.position.x, op.position.y);
    });
    particle.update();
    particle.display();
  });
}

最终效果如下图:

真实的效果是动态的,如需在 PC 上查看效果可以 点击这里

定义规则-2

另一种效果跟上面的类似,不过看起来更炫酷一点,就是在例子之间除了连线,还为这些连线填充颜色,这种规则可以定义如下:

  • 粒子之间的距离大于 100 时不做处理;
  • 粒子之间的距离小于 100 时,寻找满足距离条件的三个例子构成三角形,并为三角形填充颜色;

基于上面的规则,重新实现 darw 函数:

function draw() {
  background(255);
  particles.forEach(particle => {
    const shapes = [];
    particles.forEach(op => {
      if (particle === op) return;
      const dist = p5.Vector.dist(particle.position, op.position);
      if (dist > radius) return;
      shapes.push(op);
    });
    if (shapes.length > 1) {
      for (let i = 0; i < shapes.length - 1; i++) {
        const pointA = shapes[i], pointB = shapes[i + 1];
        const fillColor = color(255, 0, 16, 10);
        fill(fillColor);
        triangle(particle.position.x, particle.position.y, pointA.position.x, pointA.position.y, pointB.position.x, pointB.position.y);
      }
    }
    particle.update();
    particle.display();
  });
}

最终效果如下图:

可以 点击这里 查看动态效果。

其他规则

对于粒子系统而言,规则决定了粒子的表现,上面的两个示例只是简单复原了前两年比较流行的炫酷效果,但真正理解了粒子系统以后,就会发现这种规则是多么的简单。对于类似的例子系统,我们甚至可以增加鼠标交互,增加不规则受力,增加柏林噪声产生平滑扰动…

后续的文章将会有大量自然模拟,这些模拟将大量使用粒子系统。

类似文章