グローバル変数を使わずにアニメーション:Processing Tips
グローバル変数はバグの元、明日の自分に優しくない。
できることなら使わずに済ませたい。
でも、Processing でアニメーションを作りたいとき、どうしましょう?
Processing でアニメーションする場合の定石
Processing でアニメーションさせる場合、よくある構成はこんな感じです。
float グローバル変数;
setup() {
グローバル変数 = random(100);
}
draw() {
グローバル変数の値によって描画するロジック
グローバル変数 += 0.01;
}
・アニメーションの動きを制御するためのグローバル変数を宣言
・setup() でグローバル変数を初期化
・draw() でグローバル変数の値を元になんらかのロジックで描画
・draw() でグローバル変数の値をちょっと変化させる
・draw() がループすることで描画がちょっとずつ変化する
以下のアニメーションを例にすると
float radianBase;
int frameMax;
void setup() {
size(480, 480);
colorMode(HSB, 360, 100, 100, 100);
noStroke();
radianBase = 0;
frameMax = 60;
}
void draw() {
translate(width/2, height/2);
background(0, 0, 100, 100);
for (int radius = 0; radius < width; ++radius) {
float radian = 2 * PI * (radianBase + radius * 1.0 / width);
float pX = radius * cos((radian));
float pY = radius * sin(radian + cos(radian));
fill(0, 0, 40, 100);
ellipse( pX, pY, 5, 5);
ellipse(-pX, pY, 5, 5);
ellipse( pX, -pY, 5, 5);
}
radianBase += 1.0 / frameMax;
saveFrame("frames/####.png");
if (frameCount >= frameMax) {
exit();
}
}
この例では
float radianBase;
int frameMax;
の2つがグローバル変数で、radianBase でアニメーションの動きをコントロールしています。
draw() を回して描画していくため、こんな風にアニメーションの動きや色などをコントロールするのによくグローバル変数を使うことになります。
で、このコードで結局何をしているかというと、パラパラ漫画用のコマ画像を作ってるわけですよね?
要は画像ファイルができればいいんでしょう?
だったらこれでもいいんじゃないでしょうか?
void setup() {
size(480, 480);
colorMode(HSB, 360, 100, 100, 100);
noStroke();
noLoop();
}
void draw() {
translate(width/2, height/2);
float radianBase = 0;
int frameMax = 60;
for (int frames = 0; frames < frameMax; ++frames) {
background(0, 0, 100, 100);
for (int radius = 0; radius < width; ++radius) {
float radian = 2 * PI * (radianBase + radius * 1.0 / width);
float pX = radius * cos((radian));
float pY = radius * sin(radian + cos(radian));
fill(0, 0, 40, 100);
ellipse( pX, pY, 5, 5);
ellipse(-pX, pY, 5, 5);
ellipse( pX, -pY, 5, 5);
}
saveFrame("frames/" + String.format("%04d", frames) + ".png");
radianBase += 1.0 / frameMax;
}
exit();
}
・noLoop() 指定で draw() のループを止める
noLoop();
・その代わり for ループを一個増やす
for (int frames = 0; frames < frameMax; ++frames) {
・その for ループのインデックスをファイル名にして画像の保存をする
saveFrame("frames/" + String.format("%04d", frames) + ".png");
で、いっちょう上がりです!
これならグローバル変数要らないですよね?
こんなときにいいですよ
静止画のつもりで作品作っていて、後からこれ動かしたら面白いかも!ってなったときもこれなら改変が楽です。
draw() を回さないのでアニメーションの経過が画面表示されないのですが、Twitter ボット等で自動で作品を生成する場合とか、画面に表示されなくてもいいんならこれでいいですよね。
例のような短いコードなら問題にならないでしょうが、大きなプログラムになってくるとグローバル変数の危険性が増してきます。
そんなグローバル変数使わなくてもアニメーション作れますよ、というご紹介でした。
読んでくださってありがとうございました。
この記事が面白かったらサポートしていただけませんか? ぜんざい好きな私に、ぜんざいをお腹いっぱい食べさせてほしい。あなたのことを想いながら食べるから、ぜんざいサポートお願いね 💕