4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

p5.js でシンプルなパーティクル

Last updated at Posted at 2021-05-23

この記事は、以下の動画のようなシンプルなパーティクル(種類としては 2パターン)に関する処理を試した時のメモです。

冒頭の動画の内容(一つ目の作例)について

元ネタと手を加えた部分の概要

今回の内容は、以下の記事に掲載されたものを元にして、少し内容を変えて作りました。

●パーティクルを追加 | p5.js でゲーム制作
 https://fal-works.github.io/make-games-with-p5js/docs/arrange/particles/

主に対応・変更した内容などは、以下のとおりです。

  • p5.js Web Editor上にコピーして内容を修正
    • パーティクルに関係しない部分(ゲームのプレイヤーに関する部分など)の処理を削除
    • パーティクルの出現位置が上記の削除した部分に依存していたので、キャンバスの中心になるように変更
    • function setup()function draw() の部分を少し書きかえ
    • パーティクルが動いていく方向が360度の範囲になるように変更
    • 色がグレースケール(+透過)だったのをカラー(+透過)に変更
    • パーティクルが消えるまでの時間を長くなるように変更
  • p5.js Web Editor で動かしたもののファイル一式ダウンロード後、HTMLファイル 1つで動くように変更
    • p5.js のファイルは CDN を参照するように変更
    • CSS と JavaScript のファイルの内容を HTML内に直書き

なお、HTMLファイル 1つで動くように変更したのは、コピペ 1回で動作させるための一式を準備できるようするためです。

ソースコード

上記の対応を行った後のソースコードは以下のとおりです。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <script src="https://cdn.jsdelivr.net/npm/p5@1.3.1/lib/p5.js"></script>
    <style type="text/css">
      html,
      body {
        margin: 0;
        padding: 0;
      }
      canvas {
        display: block;
      }
    </style>
    <meta charset="utf-8" />
  </head>
  <body>
    <script>
      let particles = [];

      function setup() {
        createCanvas(400, 400);
        background(0, 0, 0);
      }

      function draw() {
        background(0, 0, 0);

        particles.push(createParticle(200, 200));
        particles = particles.filter(particleIsAlive);
        for (let particle of particles) {
          updatePosition(particle);
          decreaseLife(particle);
          drawParticle(particle);
        }
      }

      function createParticle(x, y) {
        let direction = random(TWO_PI);
        let speed = 2;

        return {
          x,
          y,
          vx: speed * cos(direction),
          vy: speed * sin(direction),
          life: 1, // = 100%
        };
      }

      function particleIsAlive(particle) {
        return particle.life > 0;
      }

      function updatePosition(particle) {
        particle.x += particle.vx;
        particle.y += particle.vy;
      }

      function decreaseLife(particle) {
        particle.life -= 0.01;
      }

      function drawParticle(particle) {
        push();
        noStroke();
        fill(random(255), random(255), random(255), particle.life * 255);
        square(particle.x, particle.y, particle.life * 10);
        pop();
      }
    </script>
  </body>
</html>

別バージョン(2つ目の作例)

さらに、以下のような見え方が違うものも、上記の内容をベースに作ってみました。

手を加えた部分とソースコード

2つ目の内容について、手を加えた部分の説明とソースコードを以下に記載します。

主に変更した内容は、以下のとおりです。

  • パーティクルが出現する初期位置を変更
  • 各パーティクルのスピードに幅を持たせるよう変更
  • パーティクルの色が時間経過で変化しないように変更
  • 透過率の変更度合いを少し変更

また、以下がソースコードです。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <script src="https://cdn.jsdelivr.net/npm/p5@1.3.1/lib/p5.js"></script>
    <style type="text/css">
      html,
      body {
        margin: 0;
        padding: 0;
      }
      canvas {
        display: block;
      }
    </style>
    <meta charset="utf-8" />
  </head>
  <body>
    <script>
      let particles = [];
      const CANVAS_SIZE = 400;

      function setup() {
        frameRate(60);
        createCanvas(CANVAS_SIZE, CANVAS_SIZE);
        background(0, 0, 0);
      }

      function draw() {
        background(0, 0, 0);

        // 初期位置を変更
        particles.push(
          createParticle(random(CANVAS_SIZE), random(CANVAS_SIZE))
        );
        particles = particles.filter(particleIsAlive);
        for (let particle of particles) {
          updatePosition(particle);
          decreaseLife(particle);
          drawParticle(particle);
        }
      }

      function createParticle(x, y) {
        let direction = random(TWO_PI);
        let speed = 2;

        return {
          x,
          y,
          vx: speed * random(0.1, 1.5) * cos(direction),
          vy: speed * random(0.1, 1.5) * sin(direction),
          life: 1, // = 100%
          color: [random(255), random(255), random(255)],
        };
      }

      function particleIsAlive(particle) {
        return particle.life > 0;
      }

      function updatePosition(particle) {
        particle.x += particle.vx;
        particle.y += particle.vy;
      }

      function decreaseLife(particle) {
        particle.life -= 0.01;
      }

      function drawParticle(particle) {
        push();
        noStroke();
        fill(...particle.color, (particle.life / 1.5) * 255);
        square(particle.x, particle.y, particle.life * 10);
        pop();
      }
    </script>
  </body>
</html>

今回のような内容を p5.js で実装するときは、今までは以下の Class を使ったりしていましたが、上記の filter などを組み合わせた書き方はやったことがなく参考になりました。
 ●reference | class
  https://p5js.org/reference/#/p5/class

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?