見出し画像

グローバル変数を使わずにアニメーション: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 ボット等で自動で作品を生成する場合とか、画面に表示されなくてもいいんならこれでいいですよね。

例のような短いコードなら問題にならないでしょうが、大きなプログラムになってくるとグローバル変数の危険性が増してきます。
そんなグローバル変数使わなくてもアニメーション作れますよ、というご紹介でした。

読んでくださってありがとうございました。




この記事が面白かったらサポートしていただけませんか? ぜんざい好きな私に、ぜんざいをお腹いっぱい食べさせてほしい。あなたのことを想いながら食べるから、ぜんざいサポートお願いね 💕