この記事は、以下の動画のようなシンプルなパーティクル(種類としては 2パターン)に関する処理を試した時のメモです。
p5.js を使った、シンプルなパーティクルのテスト。#p5js pic.twitter.com/ChUpvAae3o
— you (@youtoy) May 23, 2021
冒頭の動画の内容(一つ目の作例)について
元ネタと手を加えた部分の概要
今回の内容は、以下の記事に掲載されたものを元にして、少し内容を変えて作りました。
●パーティクルを追加 | 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つ目の作例)
さらに、以下のような見え方が違うものも、上記の内容をベースに作ってみました。
先ほどのものと少し違ったバージョン(p5.js を使ったパーティクル)。#p5js pic.twitter.com/eXmbYMPQRm
— you (@youtoy) May 23, 2021
手を加えた部分とソースコード
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