差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
lecture:design_with_prototyping:p5.js編:13.動きの再構成 [2021/05/18 11:54] – baba | lecture:design_with_prototyping:p5.js編:13.動きの再構成 [2021/05/25 13:25] (現在) – [パーティクル] baba | ||
---|---|---|---|
行 197: | 行 197: | ||
+ | ===== パーティクル ===== | ||
+ | この動きを一つだけで表現するのではなく、たくさんのオブジェクトに対して共通の動きを適応した代表的な手法にパーティクルがあります。これまでのサンプルを利用して、複数のボールを作成してみます。 | ||
+ | <WRAP group> | ||
+ | <WRAP half column> | ||
+ | < | ||
+ | // ボールをたくさん作るので配列で宣言する | ||
+ | var balls = []; | ||
+ | function setup() { | ||
+ | createCanvas(400, | ||
+ | | ||
+ | // ボールの個数を100個にして、ballsの配列に連想配列を初期化して追加する | ||
+ | for (let i = 0; i < 100; i++) { | ||
+ | balls.push({ | ||
+ | x: random(width), | ||
+ | y: random(height), | ||
+ | v: { | ||
+ | x: 0.0, | ||
+ | y: 0.0, | ||
+ | }, | ||
+ | }); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function draw() { | ||
+ | background(220); | ||
+ | |||
+ | // ボールの個数分の描画処理 | ||
+ | for (const ball of balls) { | ||
+ | let g = 1.0; | ||
+ | ball.x += ball.v.x; | ||
+ | ball.y += ball.v.y; | ||
+ | if (ball.y > 400 - 5) { | ||
+ | ball.v.y = 0.5 * -ball.v.y; | ||
+ | ball.y = 400 - 5; | ||
+ | } | ||
+ | ball.v.y += g; | ||
+ | |||
+ | noStroke(); | ||
+ | fill(0); | ||
+ | circle(ball.x, | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <WRAP half column> | ||
+ | {{: | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | 同じプログラムでもそれがたくさんになると、印象が変わりますね。では次は重力の無い世界のプログラムに変更してみます。ただし重力がないとただそこにとどまるだけのボールになってしまうため、初速度を設定しておきます。初速度はそのボールに設定する最初の速度です。また飛んでいってそのまま見えなくなってしまうとつまらないので、一定期間飛び続けたら自動的に最初に戻るようにします。パーティクルではこのことをライフと読んでおり、パーティクル(粒子)が発生してからなくなるまでの寿命のことを意味します。 | ||
+ | |||
+ | <WRAP group> | ||
+ | <WRAP half column> | ||
+ | < | ||
+ | // ボールをたくさん作るので配列で宣言する | ||
+ | var balls = []; | ||
+ | |||
+ | // 初速度 | ||
+ | var v0 = 0.3; | ||
+ | |||
+ | function setup() { | ||
+ | createCanvas(400, | ||
+ | |||
+ | // ボールの個数を100個にして、ballsの配列に連想配列を初期化して追加する | ||
+ | for (let i = 0; i < 100; i++) { | ||
+ | balls[i] = { | ||
+ | x: width / 2, | ||
+ | y: height / 2, | ||
+ | v: { | ||
+ | x: random(-v0, v0), | ||
+ | y: random(-v0, v0), | ||
+ | }, | ||
+ | life: random(255), | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | // 色が重なっているときの振る舞いを加算モードにする | ||
+ | // 詳細:https:// | ||
+ | blendMode(ADD); | ||
+ | } | ||
+ | |||
+ | function draw() { | ||
+ | // 画面の描画をすべてなくす | ||
+ | clear(); | ||
+ | |||
+ | // 背景色の描画 | ||
+ | background(0); | ||
+ | |||
+ | // ボールの個数分の描画処理 | ||
+ | for (const ball of balls) { | ||
+ | ball.x += ball.v.x; | ||
+ | ball.y += ball.v.y; | ||
+ | ball.life--; | ||
+ | |||
+ | // 寿命が付きたら最初に戻る | ||
+ | if (ball.life < 0) { | ||
+ | ball.x = width / 2; | ||
+ | ball.y = height / 2; | ||
+ | ball.v.x = random(-v0, v0); | ||
+ | ball.v.y = random(-v0, v0); | ||
+ | ball.life = random(255); | ||
+ | } | ||
+ | |||
+ | noStroke(); | ||
+ | fill(255, 150, 50, ball.life / 10); | ||
+ | circle(ball.x, | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <WRAP half column> | ||
+ | {{ : | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | さて、ここまでパーティクルをコーディングしてみて、パーティクルが炎や雲等の様々なコンピュータグラフィクスに利用されている可能性が理解できたかなと思います。パーティクルはウェブ等で調べても多くヒットするとおもうので、興味を持った人は自学してみてくださいね。 | ||