人工言語入門 A 2010
アニメーション、条件分岐
アニメーション
アニメーションをするには
- プログラミングの構造化が必要となる
- setup:初期化関数
- draw:メインループ関数
Processingのプログラム構造のイメージ
setup:初期化関数
- プログラムの最初に、1回だけ実行される処理を記述、アニメーションの前準備
- setupの中で行われることの多い処理
- size:画面のサイズを設定
- colorMode:カラーモードを設定
- frameRate:画面の書き換え速度を設定
draw:メインループ関数
- プログラムが終了するか、noLoop()関数が呼ばれるまでは、プログラムを実行し続ける
- ループの中で図形の場所や色、形を操作してアニメーションにする
- 画面の書き換え頻度はsetup()関数内のframerate()関数で設定する
構造化されたプログラムの例:増殖する円
//setup - 初期化関数 void setup() { size(480,480); //書き換え頻度の設定 frameRate(12); //円弧の描画をなめらかに smooth(); //背景を最初に描く background(0); } //draw - メインループ void draw() { //円の直径をランダムに設定 float diameter = random(100); noStroke(); //塗りの色をランダムに fill(random(255),random(255),random(255)); //円を描画 ellipse(random(width),random(height),diameter,diameter); }
アニメーション作成の考えかた
- setup関数で全体に共通の設定を初期化
- draw関数を繰り返す
- 背景の描画
- 図形を描く
- パラメータ(場所、色など)を微妙に変更
アニメーションの例1:円を動かしてみる
//グローバル関数の定義 (x座標、y座標) int x, y; //初期化関数 void setup(){ //画面サイズの設定 size(640,480); //フレームレート(書き換え頻度)設定 frameRate(30); //色の設定 colorMode(HSB,360,100,100,100); noStroke(); fill(200,80,80); //初期位置の座標を設定 x = 0; y = 0; } //メインループ void draw(){ //背景の再描画 background(0); //円の描画 ellipse(x,y,50,50); //x座標更新 x = x+1; //y座標更新 y = y+1; }
円が画面の幅(width)と高さ(height)から、はみ出ないようにするには?
- 方法:画面の幅 (width) を変化する変数 x の場合
- x を 画面の幅(width)で割った余りを、円のx軸上の位置にする
- 画面の幅からはみ出た場合は、また0に戻る
- y は 画面の高さ(height)の余りをとる
- よって以下のようにする
- x座標の位置 = x % width;
- y座標の位置 = y % height;
- % : 余りを計算する演算子
- 例:5 % 2 = 1 (5/4 = 2 余り1 だから)
- アニメーションの例1:円を動かしてみる – 画面からはみ出さないようにしたバージョン
//グローバル関数の定義 (x座標、y座標) int x=0, y=0; //初期化関数 void setup() { size(640,480); frameRate(30); colorMode(HSB,360,100,100,100); noStroke(); fill(200,80,80); } //メインループ void draw() { background(0); //画面からはみ出さないように座標を計算 ellipse(x%width,y%height,50,50); x = x+5; y = y+3; }
座標以外の値をアニメーションする
- アニメーションの変化するパラメータは座標だけではない
- 色をアニメーションすることも可能
- fillの値を変化させれば、色が徐々に変化していく
- アニメーションの例2:色相の変化
//グローバル変数 (色相の変化) int h = 0; //初期化関数 void setup() { size(640,480); frameRate(30); colorMode(HSB,360,100,100,100); smooth(); noStroke(); fill(200,80,80); } //メインループ//メインループ void draw(){ background(0); //色相を変数「h」で 0〜360の間で変化させている fill(h%360,80,80); //設定した塗りの色で円を再描画 ellipse(width/2,height/2,200,200); //変数の値を更新 h++; }
条件分岐
条件分岐をつかって、円が画面からはみ出ないようにしてみる
- 剰余演算子「%」を使用した方法意外のやりかたで、画面からはみ出ないようにしてみる
- 条件分岐を使用して、画面の端に来たら位置を修正するようにしてみる
- パックマンの画面移動のイメージ
条件分岐の構文
- 例 – 「もし画面の外にでたら、反対から出現する」
- もし○○したら、××せよ:条件分岐命令の典型的な例
- if〜else文:条件分岐をProcessingで記述する
if( [条件式] ){ [条件が正しい場合の処理] } else { [条件が誤っている場合の処理] }
条件「もし画面の外に出たら」→ 4つの可能性
- 画面の右端にはみ出る
- 条件式:x > width
- 画面の左端にはみ出る
- 条件式:x < 0
- 画面の下端にはみ出る
- 条件式:y > height
- 画面の上端にはみ出る
- 条件式: y < 0
それぞれの条件をif文に書いてみる
- 画面の右端からはみ出たら、左端に移動
- if(x > width) { x = 0; }
- 画面の左端からはみ出たら、右端へ移動
- if(x < 0) { x = width; }
- 画面の下端からはみ出たら、上へ移動
- if(y > height) { y = 0; }
- 画面の右端からはみ出たら
- if(y < 0) { y = height; }
条件分岐を付加したプログラム
//x座標、y座標 float x, y; //x軸方向のスピ-ド, y軸方向のスピ-ド float xSpeed, ySpeed; //初期化関数 void setup() { size(480,480); frameRate(30); colorMode(HSB,360,100,100,100); noStroke(); fill(180,100,80,80); //初期位置を画面の範囲内でランダムに決定 x = random(width); y = random(height); //スピードも -10〜10 の範囲でランダムに xSpeed = random(-10,10); ySpeed = random(-10,10); } //メインループ void draw(){ background(0); //円の描画 ellipse(x,y,40,40); //x座標更新 x+=xSpeed; //y座標更新 y+=ySpeed; //条件分岐で画面の範囲内にいるかを判定 //条件1.もし画面の右端からはみ出たら if(x > width){ //画面の左端に移動 x = 0; } //条件2.もし画面の左端からはみ出たら if(x < 0){ //画面の右端に移動 x = width; } //条件3.もし画面の下端からはみ出たら if(y > height){ //画面の上端に移動 y = 0; } //条件3.もし画面の上端からはみ出たら if(y < 0){ //画面の下端に移動 y = height; } }
壁で跳ね返ってくる動き
- 現状のプログラムを改造して、画面からはみ出た際に反対側から出現するのではなく、画面の境界を壁にして、跳ね返るように変更してみる
- ブロック崩しのイメージ
- バウンドを表現するには?
- x方向のスピードはどうなるのか?
- y方向のスピードはどうなるのか?
//グローバル変数 float x, y, xSpeed, ySpeed; //初期化関数 void setup() { size(480,480); frameRate(30); colorMode(HSB,360,100,100,100); noStroke(); fill(180,100,80,80); x = random(width); y = random(height); xSpeed = random(-10,10); ySpeed = random(-10,10); } //メインループ void draw() { background(0); ellipse(x,y,40,40); x += xSpeed; y += ySpeed; //画面の左端、もしくは右端からはみ出たら if(x > width || x < 0){ //X軸方向のスピードを反転 xSpeed *= -1; } //画面の上端、もしくは下端からはみ出たら if(y > height || y < 0){ //Y軸方向のスピードを反転 ySpeed *= -1; } }