# 粒子起手模板：Hahow Week 3-0 Particle Template

正式網址：https://newmediaart.course.monolab.world/snippets/particle-template

講師的粒子模板（OpenProcessing 上直接 Fork）：Particle 的 update() 寫規則、draw() 寫長相；開頭三行 OPC 是拉桿、顏色、色盤，邊跑邊調。這份多補了四條常用規則（重力、noise 力場、追滑鼠、分裂），先註解掉，一次打開一條。之後有粒子的示範都從這裡開始。

- **分類**：起手模板
- **行數**：81 行（p5.js 1.x／2.x）
- **在哪一堂用到**：[第 3 堂](https://newmediaart.course.monolab.world/lesson/03)

最快：到 OpenProcessing 打開 https://openprocessing.org/@cheyuwu/3033176 按 Fork（OPC 函式庫已經開好）。自己貼進空白草圖的話，要到草圖設定的 Libraries 打開 OP Configurator 3000，不然會報 OPC is not defined。先跑起來，拉拉桿；再到 update() 打開一條規則、改數字看它變成什麼；想換長相就改 draw()。

```js
// Hahow Week 3-0 Particle Template（講師的 OpenProcessing 版：https://openprocessing.org/@cheyuwu/3033176 ，直接 Fork 最快）
// 用到 OPC 拉桿：OpenProcessing 草圖設定的 Libraries 要打開「OP Configurator 3000」（Fork 就有）
let particles = [];
OPC.slider('radius', 50, 10, 100); // 拉桿：名字、預設、最小、最大
OPC.color('ballColor', '#fff'); // 顏色
OPC.palette('currentPalette', [ // 色盤：點一下換下一組
  ['#eabfcb', '#c191a1', '#a4508b', '#5f0a87', '#2f004f'],
  ['#c3dfe0', '#bcd979', '#9dad6f', '#7d6d61', '#5e574d'],
  ['#4464ad', '#a4b0f5', '#f58f29', '#7d4600', '#466995'],
]);

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(100);
}

function draw() {
  background(100);
  // 新增粒子
  for (let i = 0; i < 10; i++) {
    // 用物件格式傳遞參數
    let newP = new Particle({
      p: createVector(mouseX, mouseY),
      v: p5.Vector.random2D(),
      // color: ballColor,
      color: random(currentPalette),
      r: radius,
    });
    particles.push(newP);
  }
  // 更新與繪製所有粒子
  particles.forEach((p) => {
    p.update();
    p.draw();
  });
  // 保留存活的粒子
  particles = particles.filter((p) => p.alive);
}

// ── 以下是 ParticleClass 分頁 ──
class Particle {
  // 用物件格式接收引數 obj {a:1} -> obj.a
  constructor(args) {
    let def = {
      p: createVector(0, 0), // 位置
      v: createVector(0, 0), // 速度
      a: createVector(0, 0), // 加速度
      r: 50, // 半徑
      color: color(255),
      life: 100, // 還能活幾格
      alive: true, // 是否活著
    };
    // 覆蓋預設值（如果有引數）
    Object.assign(def, args);
    Object.assign(this, def);
  }
  // 每次更新的邏輯
  update() {
    this.life--; // 生命 -1
    this.r *= 0.99; // 半徑逐漸變小
    if (this.life < 0) {
      this.alive = false;
    }
    // ── 常用規則（這份多補的，OpenProcessing 模板上沒有）：複製一行、拿掉 // 就打開 ──
    // 重力：this.a = createVector(0, 0.1);
    // noise 力場：this.a = p5.Vector.fromAngle(noise(this.p.x * 0.005, this.p.y * 0.005) * TWO_PI * 2).mult(0.1);
    // 追滑鼠：this.a = p5.Vector.sub(createVector(mouseX, mouseY), this.p).setMag(0.1);
    // 分裂：if (this.life === 0 && particles.length < 3000) for (let k = 0; k < 2; k++) particles.push(new Particle({ p: this.p.copy(), v: p5.Vector.random2D(), r: this.r, color: this.color }));
    // 位置/速度/加速度更新
    this.p.add(this.v);
    this.v.add(this.a);
  }
  // 繪製
  draw() {
    push();
    fill(this.color);
    translate(this.p.x, this.p.y);
    circle(0, 0, this.r);
    pop();
  }
}
```

## 同類常用指令・起手模板

- [OPC 拉桿：把數字變成邊跑邊調的控制項](https://newmediaart.course.monolab.world/snippets/opc-sliders)

[回到全部常用指令](https://newmediaart.course.monolab.world/snippets)

[到 Hahow 報名](https://hahow.in/cr/creative-code)。價格與優惠以 Hahow 頁面為準。
