« Processingであの花ED風 | Main | Processingであの花ED風-メインルーチン解説 »

Processingであの花ED風-花クラス解説

前回のソースコードの解説です。

プログラムは、大きく分けて、"メインルーチン"と1つの花を描画する"花クラス"に分かれています。
メインルーチンでは、全体の表示とたくさんの花クラスのインスタンスを作成して管理します。
花クラスでは、画像を描画する位置と角度を計算して画像を描画します。

今回は、花クラスの詳細を見ていきます。ソースコード全体は前回を参照してください。まずは花クラスから。

「花」クラス

変数定義
//「花」クラス
class Flower {
  PImage img;  //「花」画像

  float currentX = 0;  //現在のX座標
  float currentY = 0;  //現在のY座標
  float currentA = 0;  //現在の角度

  float offsetX = 0;  //1フレームのX方向の移動量
  float offsetY = 0;  //1フレームのY方向の移動量
  float offsetA = 0.05;  //1フレームの回転量

  float maxW = 0;  //描画領域のX方向の最大値
  float minW = 0;  //描画領域のX方向の最小値
  float maxH = 0;  //描画領域のY方向の最大値
  float minH = 0;  //描画領域のY方向の最小値

  float alpha = 0;  //画像の透明度
  float gray = 0;  //画像のモノクロ表示の明るさ
  float hue = 0;  //画像の色調
  float saturation = 0;  //画像の彩度

  boolean isColor = false//カラーモード 初期値:false=モノクロ

…コメントの通りです。後で順次登場します。

コンストラクタ
  //コンストラクタ
  //  引数
  //    imgFile : 描画する画像イメージ
  //    downSpeed : 花が「落下」する速度の基準値
  //    downRange : 花が「落下」する幅の基準値
  Flower(String imgFile, float downSpeed, float downRange) {

…コメントの通りです。

画像読み込み
    //指定画像を読み込み
    img = loadImage(imgFile);

…コメントの通りです。

描画領域を設定
    //画像の描画領域を設定
    maxW = width + img.width;
    minW -= img.width;
    maxH = height + img.height;
    minH -= img.height;

単純に表示領域からはみ出たら、すぐにはみ出た反対側に出す方式だと、表示領域の境界付近で突然画像が現れたり消えたりする現象が発生してしまいます。それを避けるために、表示領域の外側に画像ひとつ分大きい描画領域を設定して、画像が完全に見切れてから、見切れた反対側に移動する方式にします。舞台そでみたいなものです。

Hana_1

最初の位置をランダムに設定
    //最初の位置をランダムに設定
    currentX = random(minW, maxW);
    currentY = random(minH, maxH);

描画領域の範囲内で最初の位置をランダムに設定します。

色調をランダムに設定
    //画像の色調をランダムに設定
    alpha = random(80, 96);
    saturation = random(15, 65);
    hue = random(90, 103);
    if (hue > 100) {
      hue -= 100;
    }
    gray = 100 - saturation + 30;

画像の色相をここでランダムに設定しています。

alphaは不透明度で、100のうち、80~96の範囲でランダムに設定。軽く透けるくらいにしています。

saturationは彩度で、100のうち、15~65の範囲でランダムに設定。ピンク色が中心なので彩度は抑え目です。

hueは色相で色あいの基準になるものです。100のうち、90~100の範囲と0から3の範囲でランダムに設定。かなり微妙ですが大体以下のような色になります(彩度50の場合)。

90 100/0 3

カラーモードをHSBにすると、近い色合いのものをランダムに選択したり、変化させるのに直観的に扱えるので便利です。

grayはモノクロモードの場合の明るさで、値が大きくなるほど上がるくなって100で白になります。カラーモードとの切替で違和感がないように彩度をもとに設定し、そのままだとちょっと暗かったので30を足して明るくしました。

移動量をランダムに設定
    //移動量をランダムに設定
    offsetX = random(-downRange, downRange);
    offsetY = random(downSpeed, downSpeed * 2);

単純に引数で指定した落下速度や落下幅だけだと、動きが一様になってしまうので、移動量をランダムに設定しています。
X方向(offsetX:横方向)の移動量は、マイナスの指定幅からプラスの指定幅の間でランダムに設定しています。
Y方向(offsetY:縦方向)の移動量は、指定の速度から指定の2倍の速度までの間でランダムに設定しています。

アニメーション描画
  //アニメーション描画...新しい位置を計算して描画
  void run() {

呼び出しごとに新しい描画位置を計算して、そこに描画するメソッドです。

新しいX座標を計算
    //新しいX座標を計算...描画領域を超えたら反対側へ
    currentX += offsetX;
    if (currentX > maxW) {
      currentX = minW;
    }
    else if (currentX < minW) {
      currentX = maxW;
    }

現在のX位置(currentX)にX方向の移動量(offsetX)を足して、新しい横方向の位置を算出しています。 新しい位置が描画領域の左端を超えたら右端へ、右端を超えたら左端へ設定しています。

新しいY座標を計算
    //新しいY座標を計算...描画領域を超えたら反対側へ
    currentY += offsetY;
    if (currentY > maxH) {
      currentY = minH;
    }
    else if (currentY < minH) {
      currentY = maxH;
    }

現在のY位置(currentY)にY方向の移動量(offsetY)を足して、新しい縦方向の位置を算出しています。 新しい位置が描画領域の下端を超えたら上端へ、上端を超えたら下端へ設定しています。

新しい角度を計算
    //新しい角度を計算
    currentA += offsetA;
    if (currentA > TWO_PI) {
      currentA = 0;
    }

角度として設定する値は、度分秒ではなく、ラジアンです。ラジアンのTWO_PI = 2πは360度にあたるので、角度を増やしていって、360度を超えたら0度に戻します。

画像描画
    //新しい位置で画像を描画
    draw();
  }

新しい位置が計算できたら、画像の描画を実行します。

画像描画
  //画像を描画
  void draw() {

現在の位置と現在の角度で画像を描画します。

座標系の移動
    //描画前の座標系を保存
    pushMatrix();

    //座標系を描画する位置と角度に設定
    translate(currentX, currentY, 0);
    rotate(currentA);

画像を回転した状態で描画するには、画像を描画する前に描画の基準となる"座標系"をごと回転させる必要があります。座標系は画面に表示座標とは別に独立して存在し、メインルーチンのdrawメソッドが呼び出されるときには画面に左上に設定されています。

この座標系を下図のように移動(translate)、回転(rotate)して変更してから描画します。
Hana_3
ただし、座標系を変更したままだと、他の花を描画するときに変更した座標系を基準に移動・回転して、とんでもないところに描画してしまうので、変更する前に座標系を保存(pushMatrix)して、描画し終わったら元に戻す(popMatrix)操作が必要になります。

色相を設定
    //画像に追加する色調を設定
    if (isColor) {
      tint(hue, saturation, 92, alpha);
    }
    else {
      tint(gray, alpha);
    }

カラーモードの場合は、tint命令で設定の色(色相、彩度、明るさ)を、モノクロモードの場合は、明るさを乗算しています(下図は乗算のイメージ)。

_

画像を白くしておくと、乗算する色や明るさがそのまま反映されます。

画像を描画
    //画像を描画
    imageMode(CENTER);
    image(img, 0, 0);

    //設定した座標系を破棄して前の座標系に戻す
    popMatrix();

座標系を移動しているので、イメージの描画はx=0、y=0で中心を基準に描画しています。描画し終わったら、描画のために移動した座標系をpopMatrixで破棄し、次の描画のために描画前の座標系に戻します。

カラーモード変更
  //カラーモード変更
  void changeColor() {
    isColor = !isColor;
    //Y方向の移動量を反転
    offsetY = - offsetY;
  }

カラーモードフラグを否定(tureをfalseに、falseをtrueに)設定して切り替えています。また、Y方向の移動量の符号を入れ替えて、落下方向を入れ替えています。

メインルーチンの解説は次回

|

« Processingであの花ED風 | Main | Processingであの花ED風-メインルーチン解説 »

Processing」カテゴリの記事

プログラミング」カテゴリの記事

Comments

Post a comment



(Not displayed with comment.)




« Processingであの花ED風 | Main | Processingであの花ED風-メインルーチン解説 »