yoppa.org


immediate bitwave

SFC – デザインとプログラミング 2017

動きを生みだす – アニメーションとベクトル

今回からいよいよ動きのある表現(= アニメーション)について扱っていきます。アニメーションを実現するには、まず時間を扱う基本構造を知る必要があります。Processingでは、setup(), draw() という2つのブロックにわけて、初期化と更新を行うことでアニメーションを実現しています。まず始めはこの基本構造について理解します。次に、これから動きを扱う際に、向きと大きさをもった「ベクトル」という概念を理解します。ベクトルを理解することで、位置や運動を整理して記述することが可能となります。最後に、この基本構造をベクトルを活用して簡単なアニメーションを作成します。

スライド資料

サンプルコード

サンプルコード 1

//初期化関数
void setup() {
  size(800, 600);
  frameRate(12);   //書き換え頻度の設定
  background(0);
}
//メインループ
void draw() {
  float diameter = random(100);
  noStroke();
  fill(random(255), random(255), random(255));
  ellipse(random(width), random(height), diameter, diameter);
}

サンプルコード 2

float locationX, locationY; //円の中心位置を格納する変数
float velocityX, velocityY; //円の速度を格納する変数
void setup() {
    size(800, 600); //800x600 pixelの画面を生成
    frameRate(60); //フレームレート
    locationX = width/2; //円の初期位置X
    locationY = height/2; //円の初期位置Y
    velocityX = 3; //円の初期位置X
    velocityY = 2; //円の初期位置Y
}

void draw() {
    background(0); //背景を描画
    locationX = locationX + velocityX; //円のX座標を更新
    locationY = locationY + velocityY; //円のY座標を更新
    noStroke(); //枠線なし
    fill(0, 127, 255); //塗りの色
    ellipse(locationX, locationY, 20, 20); //指定した位置に円を描画
}

サンプルコード 3

float locationX, locationY; //円の中心位置を格納する変数
float velocityX, velocityY; //円の速度を格納する変数

void setup() {
    size(800, 600); //800x600 pixelの画面を生成
    frameRate(60);  //フレームレート
    locationX = width/2; //円の初期位置X
    locationY = height/2; //円の初期位置Y
    velocityX = 3;  //円の初期位置X
    velocityY = 2;  //円の初期位置Y
}

void draw() {
    background(0); //背景を描画
    locationX = locationX + velocityX; //円のX座標を更新
    locationY = locationY + velocityY; //円のY座標を更新
    noStroke(); //枠線なし
    fill(0, 127, 255); //塗りの色
    ellipse(locationX, locationY, 20, 20); //指定した位置に円を描画

    if (locationX < 0 || locationX > width) { //もし画面の左端、または右端に到達したら
        velocityX = velocityX * -1; //X方向のスピードを反転
    }
    if (locationY < 0 || locationY > height) { //もし画面の下端、または上端に到達したら
        velocityY = velocityY * -1; //Y方向のスピードを反転
    }
}

サンプルコード 4

PVector location; //円の中心位置を格納する変数
PVector velocity; //円の速度を格納する変数
void setup() {
    size(800, 600); //800x600 pixelの画面を生成
    frameRate(60); //フレームレート
    location = new PVector(random(width), random(height));
    velocity = new PVector(random(-10, 10), random(-10, 10));
}

void draw() {
    background(0); //背景を描画
    location.add(velocity); //位置のベクトルに速度のベクトルを加算、次の位置になる

    noStroke(); //枠線なし
    fill(0, 127, 255); //塗りの色
    ellipse(location.x, location.y, 20, 20); //指定した位置に円を描画
    if (location.x < 0 || location.x > width) { //もし画面の左端、または右端に到達したら
        velocity.x = velocity.x * -1; //X方向のスピードを反転
    }
    if (location.y < 0 || location.y > height) { //もし画面の下端、または上端に到達したら
        velocity.y = velocity.y * -1; //Y方向のスピードを反転
    }
}

サンプルコード 5

int NUM = 100; //配列の数
//位置のベクトルの配列
PVector[] location = new PVector[NUM];
//速度のベクトルの配列
PVector[] velocity = new PVector[NUM];

void setup() {
  size(800, 600); //800x600pixelの画面を生成
  frameRate(60); //フレームレート
  noStroke(); //枠線なし
  fill(0, 127, 255); //塗りの色
  for (int i = 0; i < NUM; i++) { //配列の数だけ繰り返し
    //位置のベクトルの初期設定
    location[i] = new PVector(random(width), random(height));
    //速度のベクトルの初期設定
    velocity[i] = new PVector(random(-4, 4), random(-4, 4));
  }
}

void draw() {
  background(15); //背景を描画
  for (int i = 0; i < NUM; i++) { //配列の数だけ繰り返し
    //指定した位置に円を描画
    ellipse(location[i].x, location[i].y, 20, 20);
    //位置のベクトルに速度のベクトルを加算、次の位置になる
    location[i].add(velocity[i]);
    //もし画面の左端、または右端に到達したら
    if ((location[i].x > width) || (location[i].x < 0)) {
      velocity[i].x *= -1; //X方向のスピードを反転
    }
    //もし画面の下端、または上端に到達したら
    if ((location[i].y > height) || (location[i].y < 0)) {
      velocity[i].y *= -1; //Y方向のスピードを反転
    }
  }
}

サンプルコード 6

int NUM = 500; //配列の数
//位置のベクトルの配列
PVector[] location = new PVector[NUM];
//速度のベクトルの配列
PVector[] velocity = new PVector[NUM];
//塗りの色の配列
color[] col = new color[NUM];
//円の大きさ(直径)の配列
float[] diameter = new float[NUM];

void setup() {
  size(800, 600); //800x600pixelの画面を生成
  frameRate(60); //フレームレート
  noStroke();
  for (int i = 0; i < NUM; i++) { //配列の数だけ繰り返し
    //位置のベクトルの初期設定
    location[i] = new PVector(random(width), random(height));
    //速度のベクトルの初期設定
    velocity[i] = new PVector(random(-4, 4), random(-4, 4));
    //色の初期設定
    col[i] = color(random(255), random(255), random(255), 192);
    //大きさの初期設定
    diameter[i] = random(3, 40);
  }
}

void draw() {
  background(15); //背景を描画
  //配列の数だけ繰り返し
  for (int i = 0; i < NUM; i++) {
    fill(col[i]); //色を指定
    //指定した位置に円を描画
    ellipse(location[i].x, location[i].y, diameter[i], diameter[i]);
    //位置のベクトルに速度のベクトルを加算、次の位置になる
    location[i].add(velocity[i]);
    //もし画面の左端、または右端に到達したら
    if ((location[i].x > width) || (location[i].x < 0)) {
      velocity[i].x *= -1; //X方向のスピードを反転
    }
    //もし画面の下端、または上端に到達したら
    if ((location[i].y > height) || (location[i].y < 0)) {
      velocity[i].y *= -1; //Y方向のスピードを反転
    }
  }
}