
p5jsで雪を降らせよう!- 2024.12
12月になりました。北の方では雪が降る季節です。以下参考サイトを参考に雪を降らせます。
に貼り付ければすぐに試すことができます。
自分なりに解説してみます。
全体の流れとしては
setup()
配列に雪の出たを入れておく
draw()
配列に入ったそれぞれのデータを連続的に動かして表示する。
まず雪(円)を大量に描くために、雪のデータを入れるために配列を作ります。
let snows = [];
雪クラスの配列を使って表示させるコードです。そして初期設定(setup())を作ります。
function setup(){
createCanvas(windowWidth, windowHeight);
let snowNum = random(100, 200);
for (let i=0; i < snowNum; i++) {
snows.push(new Snow());
}
}
ここでは最初に作った配列にデータを入れていく操作をfor文で繰り返し作成します。作る数(繰り返し回数)は
let snowNum = random(100, 200);
で100から200 までの数字をランダムに選んでリストsnowsに追加していきます。
snows.push(new Snow());
クラスSnow()を使って雪を作っていきます。Snow()クラスは
class Snow {
x = random(0, width);
y = random(-20, -1000);
size = random(6, 20);
speed = random(1, 2);
sides = 6;
angle = TWO_PI/ this.sides;
updatePosition() {
this.y += this.speed;
if(this.y > height + 30) {
this.y = random(-20, -300);
}
}
drawSnowFlake() {
push();
stroke(255);
translate(this.x, this.y);
for (let i = 0; i < this.sides; i++) {
line(0, 0, this.size/2*cos(this.angle * i), this.size/2*sin(this.angle * i));
}
pop();
}
}
このデータは
snows.push(new Snow())
で配列に入っているものを使っています。
Snow()クラス
雪が降ってくる始点座標と形、降るスピード、結晶の形のデータを決めているのが
x = random(0, width);
y = random(-20, -1000);
size = random(6, 20);
speed = random(1, 2);
sides = 6;
angle = TWO_PI/ this.sides;
updatePosition()関数とdrawSnowFlake()関数を使って座標などの更新をして動かします。
・updatePosition()関数は雪の降るスピードと雪の表示位置を更新し続けるもの。
・drawSnowFlake()関数は雪の形を作るコードです。線6本で雪を描いています。
あとはリストsnowsに入った"雪"をdraw()関数で動かします。
function draw(){
background(30,30,55);
for(let snow of snows) {
snow.updatePosition();
snow.drawSnowFlake();
}
}
少しコードを変更して雪の形状、大きさと、スピードを変更して雪を回転するようにしています。
let snows = [];
function setup(){
createCanvas(windowWidth, windowHeight);
let snowNum = random(100, 200);
for (let i=0; i < snowNum; i++) {
snows.push(new Snow());
}
}
function draw(){
background(30,30,55);
for(let snow of snows) {
snow.updatePosition();
snow.drawSnowFlake();
}
}
class Snow {
x = random(0, width);
y = random(-20, -1000);
size = random(5, 15); // 変更部分
speed = random(1, 1.5); // 変更部分
sides = random(4, 8); // 変更部分
angle = TWO_PI/ this.sides;
ss = 0; // 追加部分
updatePosition() {
this.y += this.speed;
if(this.y > height + 30) {
this.y = random(-20, -300);
}
this.ss += 0.01; // 追加部分
}
drawSnowFlake() {
push();
stroke(255);
translate(this.x, this.y);
rotate(this.ss); // 追加部分
for (let i = 0; i < this.sides; i++) {
line(0, 0, this.size/2*cos(this.angle * i), this.size/2*sin(this.angle * i));
}
pop();
}
}