🦊
rotateとnoiseで簡単な弾幕を作る
弾幕みたいなアニメーションを作る。
コード
function setup() {
createCanvas(400, 400);
noStroke();
fill(255);
}
function draw() {
background(0);
translate(200, 200);
let r = 400;
while(r--){
const x = (frameCount*2 + noise(r)*600)%300;
rect(x-4, -2, 8, 4);
rotate(TAU/400);
}
}
こんな感じの見た目になる。座標の中心をキャンバスの中心に合わせたうえで、x軸の正方向のある場所に長方形を描き、rotateで400回等間隔でずらしながらそれを行う。その際の距離がxで、これはframeCountでずらしている。その際のオフセット(初期位置)をノイズでずらしている。
ノイズは固定されたランダム値のように用いることができる。引数が1つの場合、相当大きい数でない限りバラバラな0~1の値を返してくれる。これを300で割った余りを取る。半径300の円はこの正方形をすっぽり覆う(200のルート2倍がおおよそ282なので)。それで繰り返しのアニメーションにすると弾幕のようになるというわけ。
noise(r)に掛ける値が300ではなく600である理由
noise(r)の値は0~1なので、300を掛ければ0~300でばらけそうに思えるが、実際は違う。あそこを600から300に変えると、次のように途中に弾の飛んでこない時間ができてしまう。
これを調べるため、次のようにしてノイズの値の散らばり方を調べてみる。
function setup() {
createCanvas(600, 600);
fill(128);
noStroke();
background(0);
let r=[];
for(i=0;i<300;i++){
r.push(noise(i)*300);
//r.push((noise(i)*600)%300);
}
r.sort((a, b) => (a-b));
for(i=0;i<300;i++){
const y = r[i];
rect(i*2, 600-y*2, 2, y*2);
}
}
ご覧の通り、ノイズの値は0.5付近に集中しているので、単純に300倍だと150の近くに密集しすぎてしまう。なので、600倍して300で割った余りを取る。こうすることで値がばらけている範囲が分散していい感じになる:
これはいろいろと応用が利くのでつぶやきProcessingなどでよく使っていた。
バリエーション
background(0)をbackground(0, 40)にするだけでだいぶ違った見た目になる。
他、色を付けるなど、いろいろ応用できる。長方形の代わりに線とか円とかにしたり、色々。
Discussion