SFC - デザインとプログラミング 2016
動きを生みだす – アニメーションとベクトル
今回からいよいよ動きのある表現(= アニメーション)について扱っていきます。アニメーションを実現するには、まず時間を扱う基本構造を知る必要があります。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方向のスピードを反転 } } }