fc2ブログ

Processingレクチャー 7回目

7回目の内容をまとめます。
このレクチャーは次回のArduino特別回をもって最終回とします。


前回の動画では1フレームに同時に1つの図形しか描画しませんでした。
複数の図形を描画する場合、位置や大きさなどを描く数の分だけ制御する必要があります。

変数をx1、x2、x3…、y1、y2、y3…、と宣言してそれぞれの要素にしてもいいですが、
x1やy1の「1」は変数名の一部であって、数字を変数に置き換えて使用する事は出来ません。

そこで使うのが配列です。配列を使うと自動で番号を振られた複数の変数を宣言できます。
変数arrayをn個配列で宣言したなら、array[0]、array[1]…、array[n-1]まで作られます。
この[]内の数字なら変数を用いて制御できます。forループと組み合わせるのが簡単です。


配列の宣言の仕方

int[] hairetsu = new int[3];

これを宣言すれば、hairetsu[0]、hairetsu[1]、hairetsu[2]の3つのint型の変数が作られます。
他の型の配列を宣言したければ2つあるintをfloatやcolorなどに変更します。
hairetsuは変数名、[3]は配列の要素数を指定します。数字でなくint型の変数でも指定できます。

これで配列は宣言できますが、宣言しただけでは何も格納されていないので、
setup() 関数内などでforループを使って初期化しましょう。


マウスで操作できるプログラムの説明をします。

以前、システム変数として mouseX と mouseY を紹介しました。
これはリアルタイムでキャンパス上のマウスカーソルの座標を自動で取得します。
これを描画の各要素に使用すればマウスを動かす事で変化させる事が出来ます。


新しいシステム変数を説明します。

mousePressed
マウスボタンが押されているかを調べるシステム変数です。
何かしらマウスボタンが押されているとtrue、離しているとfalseを自動で取得します。
if文の条件文として使う事で、ボタンを押す事での変化を制御できます。
一般的に、マウスカーソルがどこの座標にあるかを判別するif文と合わせて使用します。

mouseButton
マウスのどのボタンが押されているかを調べるシステム変数です。
RIGHT、LEFT、CENTERのみ格納する事が出来、それぞれのボタンに対応します。
上記の mousePressed を用いたif文の中などで更にif文やswitch文を用いて使用します。

pmouseX、pmouseY
1フレーム前のキャンパス上のマウスカーソルの座標を自動で取得するシステム変数です。
例えばmouseX、mouseYとの差を計算する事でマウスの動く速さを計算出来ます。



イベントハンドラ関数について説明します。
これは draw() 関数とは別の関数で、マウスを動かしたりボタンを押したりなど、
特定の操作をした時のみ draw() 関数内の一番最後に自動で呼び出されます。
そのため draw() 関数内で変更された座標情報の影響を受けます。

void mouseMoved(){
}
マウスボタンを離しながら動かしている時に呼び出される関数です。
マウスを動かしていなければボタンを離していても呼び出されません。

void mouseDragged(){
}
マウスボタンを押しながら動かしている時に呼び出される関数です。
マウスを動かしていなければボタンを押していても呼び出されません。

void mousePressed(){
}
マウスボタンを押した時に呼び出される関数です。

void mouseReleased(){
}
マウスボタンを離した時に呼び出される関数です。

void mouseClicked(){
}
マウスボタンを押してその場で動かさずに離した時に呼び出される関数です。
mouseReleased() 関数も設定している時にはその関数より後に呼び出されます。

マウスを操作する以外にもキーボードを用いた操作もプログラムする事が出来ます。
詳しくは参考書を見て下さい。



ペーパーのプログラムの補足です。

表面のプログラムは後半部のif文で壁に対する跳ね返りを判定していました。

    if( x[i] < 0 || x[i] > width ) vx[i] *= -1;
    if( y[i] < 0 || y[i] > height ) vy[i] *= -1;

これはそれぞれの円の中心(x[i], y[i])がキャンパスの端を超えた際に
次のフレームからその進行方向を反転させるものです。上記のプログラムでは
x方向では0が左端でwidthが右端、y方向では0が上端でheightが下端の値になります。

ただしこのプログラムでは跳ね返る際に円周が端にめり込んでしまいます。
これを円が端に接した時に跳ね返るように変更します。
そのためには各端の値を円の半径分狭める必要があります。

    if( x[i] < r[i]/2 || x[i] > width-r[i]/2 ) vx[i] *= -1;
    if( y[i] < r[i]/2 || y[i] > height-r[i]/2 ) vy[i] *= -1;

ellipseMode() は変更していないのでCENTERです。よってr[i]は直径として使用されています。
そのため半径はr[i]/2となり、各端に加減されキャンパスの範囲が狭められています。
これで跳ね返り判定部分は大丈夫ですが、円の初期座標によっては既にめり込んでいたりします。


setup() 関数内のforループ内で配列で宣言された各変数を初期化しています。

    x[i] = random(width);
    y[i] = random(height);

この部分でx[i]とy[i]を初期化する事で、それぞれの円の中心点の初期座標を決めています。
x方向なら0からwidthまで、つまりはキャンパスの左端から右端まで、
同じくy方向なら0からheightまで、つまりは上端から下端までの値がランダムで決まります。
しかしこれでは跳ね返り判定部分で狭めた範囲の外に初期座標が決まる事もあります。

    x[i] = random(r[i]/2, width-r[i]/2);
    y[i] = random(r[i]/2, height-r[i]/2);

ここも跳ね返り判定部分と同じく範囲を狭めてやればよいのです。
ただし random() の引数に使われている以上、先にr[i]が初期化される必要があります。
r[i]の初期化部分をx[i]やy[i]の初期化より前に入れ替えます。


これで問題なく円が端にぶつかると跳ね返らせる事が出来ます。
ただし今回は円の描画は直径を用いているのに対し、各判定部分では半径を用いています。
このプログラムに限らず、r[i]やr[i]/2が混同してはプログラムミスの原因になるので、
あらかじめ ellipseMode(RADIUS); を設定して描画も判定も半径で統一する事を推奨します。
スポンサーサイト



tag: [Processing]
プロフィール

Moonwalkers

Author:Moonwalkers
メディアアート、インタラクティブメディア制作ゼミ

最新記事
タグクラウドとサーチ

カテゴリ
月別アーカイブ
ディクテーション
Polyglot Free Language Lessons Online
リンク
Twitter
検索フォーム
RSSリンクの表示
QRコード
QRコード