The Nature of Code(PDF版)からPVectorについて取り上げます。PVectorは、Processingで用意されているクラスです。Processingと絡めてJavaのクラスについて軽く勉強します。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
概要
例として、弾むボールのプログラムを書きます。以下のような流れでプログラムを書いていきます。
- PVectorを使わずに今まで通りプログラムを書く
- PVectorを使ってプログラムを書く
- Moverクラスを作ってプログラムを書く
弾むボールの描画(PVectorを使わない場合)
//Bouncing ball with no vectors float x = 100; float y = 100; float xspeed = 1; float yspeed = 3.3; void setup(){ size(200, 200); smooth(); background(255); } void draw(){ background(255); //ボールの位置の更新 x += xspeed; y += yspeed; //ボールがウィンドウから外れたときの処理 if((x > width) || (x < 0)){ xspeed = xspeed * -1; } if((y > height) || (y < 0)){ yspeed = yspeed * -1; } //ボールの描画 stroke(0); fill(175); ellipse(x, y, 16, 16); }
上記のコードは、3つのブロック(変数の初期化、setup()、draw())で出来ているイメージです。
弾むボールの描画(PVectorを使う場合)
上記のプログラムをPVector、つまりベクトルで書き換えます。ベクトルとは、向きと大きさを持つものです。余談ですが、PVectorを勉強するために高校数学のベクトルを復習しました。
//Bouncing ball with PVectors PVector location; PVector velocity; void setup(){ size(200, 200); smooth(); location = new PVector(100, 100); velocity = new PVector(1, 3.3); } void draw(){ background(255); //ボールの位置の更新 location.add(velocity); //ボールがウィンドウから外れたときの処理 if((location.x > width) || (location.x < 0)){ velocity.x = velocity.x * -1; } if((location.y > height) || (location.y < 0)){ velocity.y = velocity.y * -1; } //ボールの描画 stroke(0); fill(175); ellipse(location.x, location.y, 16, 16); }
変数x、yは位置(座標)、変数xspeed、yspeedは速度としているので、それぞれをPVectorクラスの変数location、velocityとして扱います。setup()内で、位置(location)と速度(velocity)を初期化しています。draw()内での処理は前のコードと同じですが、記述が少し変わります。
弾むボールの描画(Moverクラスを作る)
Moverクラスを作って、プログラムを整理します。クラス名は、任意のもので構いません、ここでは、仮にMoverという名前でクラスを作ります。
//Moverクラスを作る Mover mover; void setup(){ size(200, 200); smooth(); mover = new Mover(); } void draw(){ background(255); mover.update(); mover.chechEdges(); mover.display(); } class Mover{ PVector location; PVector velocity; //初期化・コンストラクタ Mover(){ location = new PVector(100, 100); velocity = new PVector(1, 3.3); } //ボールの位置の更新 void update(){ location.add(velocity); } //ボールがウィンドウから外れたときの処理 void chechEdges(){ if((location.x > width) || (location.x < 0)){ velocity.x *= -1; } if((location.y > height) || (location.y < 0)){ velocity.y *= -1; } } //ボールの描画 void display(){ stroke(0); fill(175); ellipse(location.x, location.y, 16, 16); } }
新たにMoverクラスを作ります。ここには、ボールの位置や速度、ボールに関する処理をまとめておきます。Moverクラスにフィールド(変数)とメソッド(関数)として書くことで、setup()やdraw()内の記述量が減り、処理の流れを追いやすくなったと思います。
ちなみに、以下のようにするとボールの位置と速度をランダムな値で初期化できます。
Mover(){ location = new PVector(random(width), random(height)); velocity = new PVector(random(-2, 2), random(-2, 2)); }
まとめ
The Nature of Code(PDF版)からPVectorについて取り上げました。Processingと絡めてJavaのクラスについて軽く勉強しました。引き続き、The Nature of Code(PDF版)の内容を勉強します。