| 1 | class JackieSquares extends SCPattern { |
| 2 | private BasicParameter rateParameter = new BasicParameter("RATE", 0.25); |
| 3 | private BasicParameter maxSpreadParameter = new BasicParameter("SPREAD", 0.25); |
| 4 | private BasicParameter attackParameter = new BasicParameter("ATTK", 0.3); |
| 5 | private BasicParameter decayParameter = new BasicParameter("DECAY", 0.2); |
| 6 | private BasicParameter saturationParameter = new BasicParameter("SAT", 0.7); |
| 7 | |
| 8 | SinLFO hueMod = new SinLFO(0, 360, 4000); |
| 9 | SinLFO spreadMod = new SinLFO(1, 10, 8000); |
| 10 | |
| 11 | |
| 12 | class FaceFlash { |
| 13 | Face f; |
| 14 | float value; |
| 15 | float hue; |
| 16 | boolean hasPeaked; |
| 17 | |
| 18 | FaceFlash(int n) { |
| 19 | f = model.faces.get(n % model.faces.size()); |
| 20 | hue = random(360); |
| 21 | boolean infiniteAttack = (attackParameter.getValuef() > 0.999); |
| 22 | hasPeaked = infiniteAttack; |
| 23 | value = (infiniteAttack ? 1 : 0); |
| 24 | } |
| 25 | |
| 26 | // returns TRUE if this should die |
| 27 | boolean age(double ms) { |
| 28 | if (!hasPeaked) { |
| 29 | value = value + (float) (ms / 1000.0f * ((attackParameter.getValuef() + 0.01) * 5)); |
| 30 | if (value >= 1.0) { |
| 31 | value = 1.0; |
| 32 | hasPeaked = true; |
| 33 | } |
| 34 | return false; |
| 35 | } else { |
| 36 | value = value - (float) (ms / 1000.0f * ((decayParameter.getValuef() + 0.01) * 10)); |
| 37 | return value <= 0; |
| 38 | } |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | private float leftoverMs = 0; |
| 43 | private List<FaceFlash> flashes; |
| 44 | private int faceNum = 0; |
| 45 | |
| 46 | public JackieSquares(GLucose glucose) { |
| 47 | super(glucose); |
| 48 | addParameter(rateParameter); |
| 49 | addParameter(attackParameter); |
| 50 | addParameter(decayParameter); |
| 51 | addParameter(saturationParameter); |
| 52 | addModulator(hueMod).trigger(); |
| 53 | addModulator(spreadMod).trigger(); |
| 54 | |
| 55 | flashes = new LinkedList<FaceFlash>(); |
| 56 | } |
| 57 | |
| 58 | public void run(double deltaMs) { |
| 59 | leftoverMs += deltaMs; |
| 60 | float msPerFlash = 1000 / ((rateParameter.getValuef() + .01) * 100); |
| 61 | while (leftoverMs > msPerFlash) { |
| 62 | leftoverMs -= msPerFlash; |
| 63 | faceNum += int(spreadMod.getValuef()); |
| 64 | flashes.add(new FaceFlash(faceNum)); |
| 65 | } |
| 66 | |
| 67 | for (LXPoint p : model.points) { |
| 68 | colors[p.index] = 0; |
| 69 | } |
| 70 | |
| 71 | for (FaceFlash flash : flashes) { |
| 72 | float hue = (hueMod.getValuef() + flash.hue) % 360.0; |
| 73 | color c = lx.hsb(hue, saturationParameter.getValuef() * 100, (flash.value) * 100); |
| 74 | for (LXPoint p : flash.f.points) { |
| 75 | colors[p.index] = c; |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | Iterator<FaceFlash> i = flashes.iterator(); |
| 80 | while (i.hasNext()) { |
| 81 | FaceFlash flash = i.next(); |
| 82 | boolean dead = flash.age(deltaMs); |
| 83 | if (dead) { |
| 84 | i.remove(); |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | } |
| 89 | |