yoppa.org


人工言語入門 A 2010

アニメーション、条件分岐

アニメーション

アニメーションをするには

  • プログラミングの構造化が必要となる
  • setup:初期化関数
  • draw:メインループ関数

Processingのプログラム構造のイメージ

setup:初期化関数

  • プログラムの最初に、1回だけ実行される処理を記述、アニメーションの前準備
  • setupの中で行われることの多い処理
  • size:画面のサイズを設定
  • colorMode:カラーモードを設定
  • frameRate:画面の書き換え速度を設定

draw:メインループ関数

  • プログラムが終了するか、noLoop()関数が呼ばれるまでは、プログラムを実行し続ける
  • ループの中で図形の場所や色、形を操作してアニメーションにする
  • 画面の書き換え頻度はsetup()関数内のframerate()関数で設定する

構造化されたプログラムの例:増殖する円

[code language=”java”]
//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);
}
[/code]

アニメーション作成の考えかた

  • setup関数で全体に共通の設定を初期化
  • draw関数を繰り返す
  • 背景の描画
  • 図形を描く
  • パラメータ(場所、色など)を微妙に変更

アニメーションの例1:円を動かしてみる

[code language=”java”]
//グローバル関数の定義 (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;
}
[/code]

円が画面の幅(width)と高さ(height)から、はみ出ないようにするには?

  • 方法:画面の幅 (width) を変化する変数 x の場合
  • x を 画面の幅(width)で割った余りを、円のx軸上の位置にする
  • 画面の幅からはみ出た場合は、また0に戻る
  • y は 画面の高さ(height)の余りをとる
  • よって以下のようにする
  • x座標の位置 = x % width;
  • y座標の位置 = y % height;
  • % : 余りを計算する演算子
  • 例:5 % 2 = 1 (5/4 = 2 余り1 だから)
  • アニメーションの例1:円を動かしてみる – 画面からはみ出さないようにしたバージョン

[code language=”java”]
//グローバル関数の定義 (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;
}
[/code]

座標以外の値をアニメーションする

  • アニメーションの変化するパラメータは座標だけではない
  • 色をアニメーションすることも可能
  • fillの値を変化させれば、色が徐々に変化していく
  • アニメーションの例2:色相の変化

[code language=”java”]
//グローバル変数 (色相の変化)
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++;
}
[/code]

条件分岐

条件分岐をつかって、円が画面からはみ出ないようにしてみる

  • 剰余演算子「%」を使用した方法意外のやりかたで、画面からはみ出ないようにしてみる
  • 条件分岐を使用して、画面の端に来たら位置を修正するようにしてみる
  • パックマンの画面移動のイメージ

条件分岐の構文

  • 例 – 「もし画面の外にでたら、反対から出現する」
  • もし○○したら、××せよ:条件分岐命令の典型的な例
  • if〜else文:条件分岐をProcessingで記述する

[code language=”java”]
if( [条件式] ){
[条件が正しい場合の処理]
} else {
[条件が誤っている場合の処理]
}
[/code]

条件「もし画面の外に出たら」→ 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; }

条件分岐を付加したプログラム

[code language=”java”]
//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;
}
}
[/code]

壁で跳ね返ってくる動き

  • 現状のプログラムを改造して、画面からはみ出た際に反対側から出現するのではなく、画面の境界を壁にして、跳ね返るように変更してみる
  • ブロック崩しのイメージ
  • バウンドを表現するには?
  • x方向のスピードはどうなるのか?
  • y方向のスピードはどうなるのか?

[code language=”java”]

//グローバル変数
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;
}
}
[/code]