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