yoppa.org


人工言語入門 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;
    }
}