2-6アニメーションの基本

ここまでお疲れ様でした。いよいよ、お待ちかねのアニメーションの説明に入ります。
今まで静止画を描いてきましたが、アニメーションはこの応用で実現されます。といっても仕組みは単純です。アニメーションを作るには、まず、たくさんの静止画を用意します。その際、静止画の中に描かれる人物や風景など、アニメーションさせたい対象の動きを少しずつ変えておきます。あとは、それらの静止画を素早く切り替えれば、アニメーションになるのです。
この仕組はTVアニメを作るのとまったく同じです。ただしプロセッシングの場合、繰り返し処理を用いれば、ちょっとずつ変化した静止画を書くことは手間ではありません。プロセッシングでアニメーションを作るのに必要なのは、手間ではなく、思考力ということです。
ちょっと話がそれますが、現在の世界ではこのように、思考力が膨大な手間を凌駕するケースが増えています。大げさかもしれませんが、今後の世界で必要とされる能力を鍛え、自分の可能性を広げるためにも役立つのではないでしょうか。


このページの内容

  1. アニメーションの書き方
  2. 円が移動する例
  3. 円の軌跡を消すには?
  4. 繰り返し処理を体感する1
  5. 繰り返し処理を体感する2
  6. クマさんの移動
  7. 移動する串焼き

アニメーションの書き方

アニメーションを実現するコードは、大きく三つに分けられます。アニメーションは繰り返し処理によって行われるので、一つ目に、繰り返し処理を記述する部分があります。二つ目に、繰り返処理を行う前に各種設定の初期値を記述する部分があります。三つ目は、それら両方の処理で共通して使用する設定を記述する部分です。
ひとつ目の「繰り返し処理」が記述されるのは、コードの最下部です。「void draw(){」から始まり、「}」で終了します。ふたつ目の「各種設定の初期値」はその上に記述し、「void setup(){」から始まり、「}」で終了します。三つ目の「共通して使用する設定」は、コードの最上部に記述します。
下記で、実際のコードに注釈をつけてそれを説明しています。

 //  共通設定を記述する部分開始
int x;
//  共通設定を記述する部分終了

//  各種設定の初期値を記述する部分開始
void setup(){
  size(480,270);
  background(200,200,200);
  x = 0;
}
//  各種設定の初期値を記述する部分終了

//  繰り返し処理開始
void draw(){
  x++;
  ellipse(x,height/2,50,50);
}
//  繰り返し処理終了

円が移動する例

上記コードを実行しましょう。下記のように、円が左から右に移動するアニメーションが実行されます。

キャンバス内(画面灰色の部分)を押すと、停止or停止解除します。長押しすると、再起動します。これは同じ内容のプログラムをjavascriptという言語で作成し、web上で見られるようにしたものです。Processingをjavascriptに移植したp5.jsというライブラリを使っています。)

下記では、注釈でコード内容を解説しています。注釈がついているだけで、コード自体は上記とまったく同じものです。

 //  共通設定を記述する部分開始
int x;  //変数xを宣言する。(円の中心のx座標を格納する)
//  共通設定を記述する部分終了

//  各種設定の初期値を記述する部分開始
void setup(){
  size(480,270);  //画面のサイズを指定する
  background(200,200,200);  //画面の背景色を指定する
  x = 0;  //円の中心のx座標に0を設定する。
}
//  各種設定の初期値を記述する部分終了

//  繰り返処理開始
void draw(){
  x++;  //繰り返しのたびに、円の中心のx座標を1ずつ増やす。(右に移動する)
  ellipse(x,height/2,50,50);  //円を記述する
}
//  繰り返処理終了

draw()の中で、円の中心のX座標を更新し(右に1pxずらし)、その後、円を描いています。draw()の中の処理は人間の目では追えない速度で繰り返されます。つまり、円の中心座標を少しだけずらした円を素早く何度も描くことによって、円が左から右に移動するように見せているのです。これは簡単な例ですが、基本的にはこのような仕組みでアニメーションは作られます。


円の軌跡を消すには?

上記の例では、下記のように円の軌跡が残ってしまいます。これを消すにはどうしたらよいでしょうか?

2-6-a.png

そのためには円を描く処理と、背景を描く処理(画面を背景色で塗りつぶす処理)を交互に行えばよいのです。画面を背景色で塗りつぶし、その上に円を描き、再び背景色で画面を塗りつぶし(このとき円は塗りつぶされて消える)、少し移動させた円を描く・・・といった作業を繰り返すことで、軌跡を残さずに円を移動させることができます。
下記がそのコードです。変更点は、background()という処理を、繰り返しのたびに(draw()の中で)行うようにしただけです。

int x;
void setup(){
  size(480,270);
  x = 0;
}
void draw(){
  background(200,200,200);  //繰り返しのたびに、画面を背景色で塗りつぶす。
  x++;
  ellipse(x,height/2,50,50);
}

実行結果は、下記のようになります。


繰り返し処理を体感する1

draw()の中の処理は、一秒間に60回という速さで繰り返されます。アニメーションがなめらかに見えるためには、このような素早い処理が必要なのです。下記では繰り返しによってアニメーションが実現されることを実感するために、あえて繰り返しの速度を遅くしました。
下記コードでは、setup()の中で、FrameRate(2)という処理を記述しています。こうすると、一秒間に二回という速度でdraw()の中の処理が繰り返されるようになります。

frameRate(一秒間の繰り返し回数);

frameRate()を記載しない場合、一秒間の繰り返し回数はデフォルトの60回になります。

int x;
void setup(){
  background(200,200,200);
  size(480,270);
  x = 0;
  frameRate(2);	//繰り返しを遅くする設定
}
void draw(){
  x+=25;
  ellipse(x,height/2,50,50);
}

上記を実行すると、下記のように円が軌跡を残しながらカクカクと動いていきます。繰り返し処理によって、アニメーションが行われていることが実感できると思います。
(下記のアニメーションは繰り返し回数を低く設定したたため、画面のタップやクリックによる停止や停止解除、再起動の反応が鈍くなっています)


繰り返し処理を体感する2

下記では、上記コードを変更し、繰り返しのたびに背景画像を更新するようにしました。これで軌跡がなくなります。

int x;
void setup(){
  size(480,270);
  x = 0;
  frameRate(2);
}
void draw(){
  background(200,200,200);  //背景の更新処理(画面を背景色で塗りつぶす)
  x+=25;
  ellipse(x,height/2,50,50);
}

実行結果は下記のようになります。


クマさんの移動

では今までに描いた静止画をアニメーションにしましょう。まずはクマさんを移動させるアニメーションを作ります。
下記のコードは、今までに作ったクマさんを描く処理をdraw()の中に書いただけです。

int x;
void setup() {
  size(480, 270);
  x = width/2;
}
void draw() {
  background(200, 200, 200);  //背景の更新処理(画面を背景色で塗りつぶす)

  fill(198, 59, 6);  //茶色
  ellipse(x- 50, height/2 -60, 60, 60);  //左耳
  ellipse(x+ 50, height/2 -60, 60, 60);  //右耳
  fill(250, 111, 96);  //ピンク
  ellipse(x- 50, height/2 -60, 30, 30);  //左耳の内側
  ellipse(x+ 50, height/2 -60, 30, 30);  //右耳の内側
  fill(198, 59, 6);  //茶色
  ellipse(x, height/2, 150, 150);  //顔
  fill(0, 0, 0);  //黒
  ellipse(x- 20, height/2 -20, 20, 40);  //左目
  ellipse(x+ 20, height/2 -20, 20, 40);  //右目
  line(x- 20, height/2 + 30, x+ 20, height/2 + 30);  //口
}

実行結果は下記になります。クマさんは画面中央に表示されたまま動きません。

2-4-d.png

ではクマさんが動くようにしてみます。
クマさんは丸や円、線から描かれていますが、上記コードでは、これらの図形のx座標がすべて変数xから求められるようになっています。そのため、たったひとつ変数xの値を変えるだけで、クマさんを構成する円や線の座標がすべて変わります。となると、もうお分かりでしょう。繰り返しのたびに変数xの値を少しずつ変化させれば、クマさんが移動するアニメーションになるのです。
下記はクマさんが動かすコードです。上記コードとの違いは、変数xをdraw()のたびに変化させているだけです。たったこれだけのことで、静止画がアニメーションになります。

 int x;  //クマさんのx座標の元になる変数
void setup() {
  size(480, 270);
  x = 0;  //変数xの初期値
}
void draw() {
  background(200, 200, 200);  //背景の更新処理(画面を背景色で塗りつぶす)

  x++;  //繰り返しのたびに、1ずつ大きくする(右に移動させる)

  fill(198, 59, 6);  //茶色
  ellipse(x- 50, height/2 -60, 60, 60);  //左耳
  ellipse(x+ 50, height/2 -60, 60, 60);  //右耳
  fill(250, 111, 96);  //ピンク
  ellipse(x- 50, height/2 -60, 30, 30);  //左耳の内側
  ellipse(x+ 50, height/2 -60, 30, 30);  //右耳の内側
  fill(198, 59, 6);  //茶色
  ellipse(x, height/2, 150, 150);  //顔
  fill(0, 0, 0);  //黒
  ellipse(x- 20, height/2 -20, 20, 40);  //左目
  ellipse(x+ 20, height/2 -20, 20, 40);  //右目
  line(x- 20, height/2 + 30, x+ 20, height/2 + 30);  //口
}

移動する串焼き

串焼きも移動するようにしてみましょう。

int x;
void setup() {
  size(480, 270);
  x = 0;
}
void draw() {
  background(200, 200, 200);  //背景の更新処理(画面を背景色で塗りつぶす)
  x++;

line(x - 70,height/2 + 70,x + 70 ,height/2 - 70); //クシ
fill(255,0,0);
ellipse(x - 25,height/2 + 25,50,50);  //左下の丸
fill(0,255,0);
ellipse(x,height/2,50,50);  //真ん中の丸
fill(0,0,255);
ellipse(x + 25,height/2 - 25,50,50);  //右上の丸
}