AsanaThankshackathon/VSTowers
authorVincent Siao <vincentsiao@gmail.com>
Sun, 24 Nov 2013 00:51:57 +0000 (16:51 -0800)
committerVincent Siao <vincentsiao@gmail.com>
Sun, 24 Nov 2013 00:51:57 +0000 (16:51 -0800)
SugarCubes.pde
VincentSiao.pde [new file with mode: 0644]

index 40f9a764ed1a782ca5cb4e1e01e2a4cdb96b85fc..6651e18affbe50a8b8f5638ce3246c4ee4b66416 100644 (file)
@@ -66,6 +66,9 @@ LXPattern[] patterns(GLucose glucose) {
     new TimSpheres(glucose),
 
 
     new TimSpheres(glucose),
 
 
+
+    // Vincent
+    new VSTowers(glucose),
     
     // Toby
     new GlitchPlasma(glucose),
     
     // Toby
     new GlitchPlasma(glucose),
diff --git a/VincentSiao.pde b/VincentSiao.pde
new file mode 100644 (file)
index 0000000..48a368e
--- /dev/null
@@ -0,0 +1,119 @@
+class VSTowers extends SCPattern {
+  private BasicParameter saturationParameter = new BasicParameter("SAT", 80, 0, 100);
+  private BasicParameter attackParameter = new BasicParameter("ATTK", 0.96, 0.1, 1.0);
+  private BasicParameter decayParameter = new BasicParameter("DECAY", 0.7, 0.1, 1.0);
+  private SawLFO hueLfo = new SawLFO(0, 360, 20000);
+
+  private Map<Tower, Boolean> towerOn;
+
+  class TowerFlash {
+    Tower t;
+    float value;
+    float maxVal;
+    float hue;
+    boolean hasPeaked;
+
+    TowerFlash() {
+      do {
+        t = model.towers.get(floor(random(model.towers.size())));
+      } while (towerOn.get(t));
+      towerOn.put(t, true);
+      hue = (hueLfo.getValuef() + 50*(random(2)-1.0f)) % 360;
+      value = 0.0;
+      maxVal = random(0.4) + 0.6;
+    }
+
+    boolean run(double deltaMs) {
+      if (!hasPeaked) {
+        float atk = attackParameter.getValuef();
+        float atkDuration = 10000 * (1/sqrt(atk) - 1.0f);
+        value = value + (float)deltaMs / atkDuration;
+        if (value >= maxVal) {
+          value = maxVal;
+          hasPeaked = true;
+        }
+        return false;
+      } else {
+        float dec = decayParameter.getValuef();
+        float decDuration = 10000 * (1/sqrt(dec) - 1.0f);
+        value = value - (float)deltaMs / decDuration;
+        return value <= 0;
+      }
+    }
+  }
+
+  public VSTowers(GLucose glucose) {
+    super(glucose);
+    addParameter(saturationParameter);
+    addParameter(attackParameter);
+    addParameter(decayParameter);
+    addModulator(hueLfo).trigger();
+    flashes = new LinkedList<TowerFlash>();
+    towerOn = new HashMap();
+    for (Tower t : model.towers) {
+      towerOn.put(t, false);
+    }
+  }
+
+  private List<TowerFlash> flashes;
+  private float accDelta = 0;
+
+  public void run(double deltaMs) {
+    accDelta += deltaMs;
+    float rate = lx.tempo.rampf();
+    float msPerFlash = 5000 * (1/sqrt(rate) - 1.0f);
+    if (accDelta >= msPerFlash) {
+      accDelta -= msPerFlash;
+      if (flashes.size() < model.towers.size()) {
+        flashes.add(new TowerFlash());
+      }
+    }
+    for (LXPoint p : model.points) {
+      if (random(1) < 0.2) {
+        colors[p.index] = 0;
+      }
+    }
+    for (TowerFlash tf : flashes) {
+      for (LXPoint p : tf.t.points) {
+        float towerHeight = model.yMin + tf.value * (model.yMax - model.yMin);
+        if (p.y <= towerHeight) {
+          colors[p.index] = lx.hsb(
+            (tf.hue + tf.value*50 - p.y/2) % 360,
+            saturationParameter.getValuef(),
+            tf.value*100);
+        }
+      }
+      if (tf.hasPeaked) {
+        float towerMaxHeight = model.yMin + tf.maxVal * (model.yMax - model.yMin);
+        Cube top = tf.t.cubes.get(tf.t.cubes.size()-1);
+        for (int i = tf.t.cubes.size()-1; i >= 0; --i) {
+          Cube c = tf.t.cubes.get(i);
+          float maxY = c.points.get(0).y;
+          for (LXPoint p : c.points) {
+            maxY = max(maxY, p.y);
+          }
+          if (towerMaxHeight < maxY) {
+            top = c;
+          }
+        }
+        for (LXPoint p : top.points) {
+          if (tf.value > 0.5) {
+            colors[p.index] = lx.hsb(0, 0, tf.value*100);
+          } else if (random(1) < 0.2) {
+            colors[p.index] = 0;
+          }
+        }
+      }
+    }
+    // Run flashes and remove completed ones
+    Iterator<TowerFlash> it = flashes.iterator();
+    while (it.hasNext()) {
+      TowerFlash flash = it.next();
+      if (flash.run(deltaMs)) {
+        towerOn.put(flash.t, false);
+        it.remove();
+      }
+    }
+  }
+}
+