コンピュータプログラミングI(3)
アニメーション

June 22, 2017

Nakajima, Yajima
Iwai, Tatsuta
Kakizaki, Ikeda

このスライドの使い方

テキスト等がはみ出した場合は、フォントサイズを小さくして調整する。 「S」 キーで小さく、「B」 キーで大きくなる。また、 下記のキーボード操作が使用できる。(一部キー操作は IE のみ対応)

「←」 or 「Page Up」 前のスライドに戻る
「→」 or 「Page Down」 or「スペース」 次のスライドに進む
「Home」 and 「End」 先頭(Home)または最後(End)のスライドへ移動
「C」 or 「contents?」 をクリック スライド一覧の表示
「F11」 or 「Ctrl+Shift+F (Win)」, 「Cmd+Shift+F (Mac)」 フルスクリーン表示と通常表示の切り替え
「F」 フッタの表示と非表示の切り替え
「A」 全スライド表示に切替 (印刷時に使う)
「S」「-」/「B」「+」 フォントサイズの大(B) 小(S)

本日のゴール

サンプルの動かし方

アニメーションの原理(教科書 pp.53-61)

パラパラまんがのように少しずつ違った絵を順番に書くために、プログラムを次の部分に分けて考える

void setup() {
    ........
    ........
    アニメーションを開始する前に一度だけ実行する命令を書く部分
    ........
    ........
}

void draw() {
    ........
    ........
    アニメーションの1コマを描くために、一定時間間隔で何回も実行する命令を書く部分
    ........
    ........
}

アニメーションの原理(教科書 pp.53-61)

例題: 円が移動するアニメーション

int x;
void setup() {
  size(480,120);
  noStroke();
  fill(0, 0, 0);
  x = 10;
}
void draw() {
  x++;
  background(255, 255, 255);
  ellipse(x, 60, 40, 40);
}

void setup()の後の{と}の間には、アニメーションを開始するための準備を書く この部分は最初に1回だけ実行される
例えば、ウィンドウのサイズを設定したい場合は、ここにsize命令を書く
上のプログラムでは、変数xを10に設定し、480px x 120pxのウィンドウを開き、 外形線と塗りつぶす色を設定している

void draw()の後ろの{と}の間には、アニメーションの1コマ分を書くための命令を書く
この部分は、自動的に一定時間間隔で何度も実行される
上のプログラムでは、変数xを1増やし、一旦白で画面を塗りつぶし、 変数xの位置に円を描いている

例題: 円が移動するアニメーション(図)

例題: 円が移動するアニメーション (つづき)

int x;
void setup() {
  size(480,120);
  noStroke();
  fill(0, 0, 0);
  x = 10;
}
void draw() {
  x++;
  background(255, 255, 255);
  ellipse(x, 60, 40, 40);
}

変数xに注目

試しに、上のプログラムを改造して左や下に円を動かしてみよう
また、background(255, 255, 255);を削除したときのアニメーションを観察してみよう

例題: ウィンドウの端まで行くと、また反対の端から表れる

円がウィンドウの端まで行くと、また反対の端から表れるようなアニメーションを考えよう
そのためには、「割ったときの余りを求める」演算子 % を使う

アニメーション中、変数 x が1ずつ増えているとして、円を描く命令を以下のように書く

ellipse(x % width, 60, 40, 40);

(※ width は「ウィンドウの幅」が入っているProcessingの組込み変数)

「xをwidthで割った余り」の位置に円を描くので、一旦右端まで移動すると、 再び左から始まるようなアニメーションになる

さまざまなアニメーション: 重力

前の例題のプログラムを改造し、 円をボールに見立てて、重力によって落下するアニメーションを行ってみよう

float y;               //<-- ボールのy座標
float speed;           //<-- ボールの速度
float gravity;         //<-- 重力加速度

void setup() {
  size(200, 480);
  noStroke();
  fill(0, 0, 0);
  y = 0;
  speed = 0;
  gravity = 9.8 / 60;  //<-- 1/60秒あたりの重力加速度
}

void draw() {
  speed += gravity;    //<-- 速度に重力加速度を加算する
  y += speed;          //<-- ボールが速度ぶん移動する

  background(255, 255, 255);
  ellipse(100, y, 40, 40);
}

※ float は、小数点以下を含む値を入れることができるデータ型

練習(3-1)

  1. 前の落下するボールのプログラムを改造し、
    ボールを速度12で上に打ち上げた際の落下をアニメーションで描こう
    ボールの最初の位置も打ち上げた様子がわかりやすいように調整すると良い
  2. ボールを斜め上に打ち上げたときの動きをアニメーションで描こう
    そのためには、x軸方向にもボールを移動させる
    [ サンプル ]

さまざまなアニメーション: 回転運動(1)(教科書 pp.106-107)

曲線を描くために必要なこと: sin, cos (三角関数)を使いこなす

まず、円の座標を考えてみよう

R: 円の半径, x, y: 円上の点, Θ: 角度

ここで
  x = R * cosΘ
  y = R * sinΘ
という式が成り立つ

Θ を0度から360度まで一周させれば、円の形をした座標が得られる

さまざまなアニメーション: 回転運動(2)(教科書 pp.106-107)

int r;          // <-- 円の半径
float x, y;     // <-- x, y座標
int theta;      // <-- 角度(度数法)
float rad;      // <-- 角度(ラジアン)

void setup() {
  size(400, 400);
  noStroke();
  fill(0, 0, 0);
  r = 100;
  theta = 0;
}

void draw() {
  theta++;
  rad = radians(theta);
  x = r * cos(rad);
  y = -r * sin(rad);

  background(255, 255, 255);
  ellipse(x + 200, y + 200, 40, 40);
}

練習(3-2)

  1. 前の例題のプログラムを改造し、 徐々に円の半径が大きくなるようにして、
    ボールが渦巻状に動くようしてみよう
  2. 円形に動くボールを2つに増やし、 サンプルのようなアニメーションを描こう
    [ サンプル ]

インタラクティブなアニメーション(1): マウスを追いかけるボール(教科書 pp.56-61)

void setup() {
  size(480, 120);
  noStroke();
  fill(0, 0, 0, 40);
}

void draw() {
  ellipse(mouseX, mouseY, 10, 10);
}

練習(3-3)

  1. 例題のプログラムを改造し、 マウスの軌跡を描くのではなく、 一つのボールがずっとマウスポインタを追いかけるようにしてみよう

インタラクティブなアニメーション(2): マウスクリックを検出する(教科書 pp.63-67)

マウスのボタンの状態によってアニメーションの動作を変えるためには、 「もし、ボタンが押されていたら XXXX する」というプログラムを書く必要がある

「もし ○○ であればXXXXする」という処理を記述するために、if文を使う

if (test) {
  条件を満たしたときの処理の中身
}

「test」の部分には、 関係演算子 を使った式を記述する.testがtrue(成り立っている)であれば{}内を実行する. testがfalse(成り立っていない)であれば{}内は実行されない

また「もし ○○ であればXXXXする そうでなければYYYYする」という記述もできる

if (test) {
  条件を満たしたときの処理の中身
}
else {
  条件を満たさなかったときの処理の中身
}

※ for文と同様に、 「中身」が1つの文のときは中カッコ ({, }) を省略できる

インタラクティブなアニメーション(2): マウスクリックを検出する(教科書 pp.63-67)(つづき)

「条件」にはさまざまな状況を判定する式を書けるが、 今回は「マウスのボタンが押されているかどうか」という条件を考えよう

次のようなif文を書くことができる

if (mousePressed == true) {
  マウスのボタンが押されているときの処理
}
if (mousePressed == true) {
  マウスのボタンが押されているときの処理
}
else {
  マウスのボタンが押されていないときの処理
}

mousePressedは、マウスのボタンが押されているかどうかを表す組み込み変数(Processingによって自動的に作られている変数). マウスボタンが押されていればProcessingによって自動的にtrueが保存されていて, 押されていなければfalseが保存されている

インタラクティブなアニメーション(2): マウスクリックを検出する(教科書 pp.63-67)(つづき)

mousePressedは,関係演算子の計算結果を保存するboolean型の変数なので,== trueを省略し,以下のように記述することもできる.

if (mousePressed) {
  マウスのボタンが押されているときの処理
}
if (mousePressed) {
  マウスのボタンが押されているときの処理
}
else {
  マウスのボタンが押されていないときの処理
}

インタラクティブなアニメーション(2): マウスクリックを検出する(教科書 pp.63-67) (つづき)

マウスのボタンを押したときに、マウスの位置にボールを描く

void setup() {
  size(480, 120);
  noStroke();
}

void draw() {
  background(255, 255, 255);
  fill(255, 255, 255);
  if (mousePressed == true) {
    fill(0, 0, 0);
  }
  ellipse(mouseX, mouseY, 40, 40);
}

drawの中では、まず塗りつぶす色を背景と同じ白に設定する
次に、if文でマウスのボタンが押されているかチェックし、
押されているときだけ色を黒に変える
(押されていなければ何もしない (元で設定した白のままになる))

最後にマウスの指す位置に円を描く

インタラクティブなアニメーション(2): マウスクリックを検出する(教科書 pp.63-67) (つづき)

マウスのボタンを押したときと、押していないときで ボールの大きさを変える

void setup() {
  size(480, 120);
  noStroke();
  fill(0, 0, 0);
}

void draw() {
  background(255, 255, 255);
  if (mousePressed == true) {
    ellipse(mouseX, mouseY, 80, 80);
  }
  else {
    ellipse(mouseX, mouseY, 40, 40);
  }
}

drawの中のif文では、マウスのボタンが押されているかチェックし、

if文では、forループのようにさまざまな条件を扱うことが可能
次回、詳しいやり方を学ぼう

練習(3-4)

  1. 例題「重力により落下するアニメーション」を改造し、 マウスのボタンを押した位置から上にボールを打ち上げ、 落下する様子をアニメーションで描きなさい
    [ サンプル ]

演習問題

問題1

  1. sinまたはcosを用いて正方形が単純往復するアニメーションを描くプログラムを作りなさい スケッチ名: enemy
    スケッチフォルダ内の.pdeファイルのみを提出
    [ サンプル ]
  2. マウスのボタンを押した場所から弾丸が発射されるようなプログラムを作りなさい
    スケッチ名: bullet
    スケッチフォルダ内の.pdeファイルのみを提出
    [ サンプル ]

演習問題

問題2

問題1の2つのアニメーションを合体させ、 サンプルのようなゲーム風のアニメーションを描くプログラムを作りなさい
スケッチ名: bulletAndEnemy
スケッチフォルダ内の.pdeファイルのみを提出
[ サンプル ]