日常の進捗

主に自分のための,行為とその習慣化の記録

Re: 波紋

yetirom.hatenablog.com

イエティが描いていた波紋のプログラムで,困っていたところについて幾つか考えて描いてみた.

要件としては

  • クリックしたら波紋が発生
  • クリックしてなくても波紋が広がっていくと👌
  • 波紋の数が増えると👌👌

波紋を作るのに必要な変数(括弧内は僕のプログラムの変数名)は

  • クリックした際の位置座標(PVectorのpos)
  • 波紋の大きさ(diameter)
  • 色(hue,transparent)
  • 波紋が大きくなるときの増やす加減(inc)

という感じだけど,1つ増やすごとにこれを複数つくるのは嫌だったのでクラスでまとめた.Rippleクラスが波紋自体を定義していて,RippleSystemクラスがRippleクラスを管理するようなイメージ.クラスを含むオブジェクト指向プログラミングは最初良く分からないけど,分かると短く色んなものを作れて便利なのでオススメ.配列を変数分用意しても作れるかもしれない.

こういうことも出来るよというので書きました.

コード

RippleSystem rippleSystem;
void setup() {
  size(960, 540, P2D);
  colorMode(HSB, 360, 100, 100, 100);
  rippleSystem = new RippleSystem();
}

void draw() {
  background(0, 0, 0);
  rippleSystem.render();
}

void mouseMoved() {
    if(random(1) > 0.8){
  rippleSystem.ripples.add(new Ripple(mouseX, mouseY));
    }
}

class RippleSystem {
  ArrayList<Ripple> ripples;
  RippleSystem() {
    ripples = new ArrayList<Ripple>();
  }
  void render() {
    ArrayList<Ripple> removes = new ArrayList<Ripple>();
    for (Ripple ripple : ripples) {
      ripple.update();
      ripple.draw();
      if (ripple.isBordered) {
        removes.add(ripple);
      }
    }
    for (Ripple removeRipple : removes) {
      ripples.remove(removeRipple);
    }
  }
}

class Ripple {
  PVector pos;
  float diameter = 0;
  float inc = 10;
  float transparent = 100;
  boolean isBordered = false;
  float hue = random(180,240);
  Ripple(float x, float y) {
    pos = new PVector(x, y);
  }
  void update() {
    diameter += inc;
    transparent -= 1;
    if (diameter > sqrt(sq(width*2)+sq(height*2))) {
      isBordered = true;
    }
  }
  void draw() {
    noFill();
    strokeWeight(5);
    stroke(hue, 80, 100, transparent);
    ellipse(pos.x, pos.y, diameter, diameter);
  }
}