アニメーション

Processingでは一定間隔で処理を繰り返し実行することで描いたものを動かすことができます。

関数の説明でシステムが定義しているsetup()のことを取り上げました。

setup()はプログラム実行時にシステムが最初に1度だけ呼び出す関数です。

void setup() {
  一度だけ処理する内容
}

このsetup()以外にシステムが定期的に呼び出すdraw()関数があります。

draw()はプログラム実行中はずっと、何度も等間隔で呼ばれます。

デフォルトでは1秒間に60回のペースで呼び出しています。

つまり、draw()のブロックの中でなにかを描画するコードがあると、1秒間に60回描画することとなります。

void draw() {
  1秒間に60回実行する内容
}

これをフレームといい、この場合60fps相当の描画を行っていることとなります。

この動作を使って、描画する図形の座標をdraw()が呼ばれるたびに変更すると、画面の中を図形が動きます。

float x=0;
void setup() {
  size(500,500);
}
void draw() {
  background(255);
  x+=1;
  drawMato(x,250);
}
void drawMato(float x,float y) {
  noFill();
  strokeWeight(10);
  ellipse(x,y,100,100);
  strokeWeight(5);
  ellipse(x,y,65,65);
  strokeWeight(12);
  ellipse(x,y,30,30);
}

このコードは的が画面左から右へ移動します。

ここで注意するのが変数の扱いです。繰り返しで説明した変数のスコープについて、関数もブロックがあるのでブロック内で定義した変数(引数を含む)はローカル変数となり、関数を抜けるとなくなります。

このコードで関数の外に定義しているx変数はグローバル変数です。drawMato()の引数xとは別のものとなります。

このコードでもわかるようにx座標を増やしていくと図形は右に移動します。なので、x座標を減らしていくと図形は左に移動します。

y座標も同じように増やすと下へ、減らすと上へ移動します。この理屈を使って的を画面の中でうろうろ動くようにしてみましょう。

float x=250,y=250;
int dx=2,dy=3;
void setup() {
  size(500,500);
}
void draw() {
  background(255);
  x+=dx;
  y+=dy;
  if (x < 50 || x > width-50) {
    dx *= -1;
  }
  if (y < 50 || y > height-50) {
    dy *= -1;
  }
  drawMato(x,y);
}
void drawMato(float x,float y) {
  noFill();
  strokeWeight(10);
  ellipse(x,y,100,100);
  strokeWeight(5);
  ellipse(x,y,65,65);
  strokeWeight(12);
  ellipse(x,y,30,30);
}

1行目は的の座標です。2行目はdxはx座標、dyはy座標を変化させる値です。

8行目でx座標をdxずつ変化させています。

9行目でy座標をdyずつ変化させています。

10〜12行目でもし、的が画面の左端もしくは右端に触れたらdx変数の値の符号を切り替えています。

-1をかけることで、もしdxの値の符号がプラスのときはマイナスとなり、マイナスのときはプラスとなります。

13〜15行目ではx座標と同じことをやっています。

描画する座標をマウスの座標にするとマウスに図形がついていく動作をします。

void setup() {
  size(500,500);
}
void draw() {
  background(255);
  noStroke();
  fill(255,165,0);
  ellipse(mouseX,mouseY,50,50);
}

8行目で円を描画する座標にmouseX,mouseYを使ってマウスポインタの座標を中心に描画しています。

このコードを少し改造します。

void setup() {
  size(500,500);
  background(255);
}
void draw() {
  noStroke();
  if (frameCount % 10 == 0) {
    fill(255,0,0);
  } else {
    fill(255,165,0);
  }
  ellipse(mouseX,mouseY,50,50);
}

frameCount変数を使ってdraw()が呼び出される一定間隔(このコードでは10回に1回)で円の色を赤くしています。