/************************************************************** * WORKING PATTERNS **************************************************************/ import java.util.List; import java.util.LinkedList; class AKPong extends SCPattern { private final BasicParameter speed = new BasicParameter("Speed", 0); private final BasicParameter leftKnob = new BasicParameter("Left", 0.5); private final BasicParameter rightKnob = new BasicParameter("Right", 0.5); private final float R = 20; private final float W = 20; private final float H = 80; private final float PADDLE_STEP = 5; private float oldLeft = leftKnob.getValuef(); private float oldRight = rightKnob.getValuef(); private Paddle left = new Paddle(model.xMin, model.cy - H / 2, model.xMin + W, model.cy + H / 2); private Paddle right = new Paddle(model.xMax - W, model.cy - H / 2, model.xMax, model.cy + H / 2); private Ball ball = new Ball(); class Paddle { float x1, y1, x2, y2; public Paddle(float x1, float y1, float x2, float y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } public boolean contains(LXPoint p) { return p.x > x1 && p.x < x2 && p.y > y1 && p.y < y2; } public void moveUp() { float adj = 9 * speed.getValuef(); if (y2 + PADDLE_STEP < model.yMax) { y1 += PADDLE_STEP + adj; y2 += PADDLE_STEP + adj; } else { y1 = model.yMax - H; y2 = model.yMax; } } public void moveDown() { float adj = 15 * speed.getValuef(); if (y2 - PADDLE_STEP > model.yMin) { y1 -= PADDLE_STEP + adj; y2 -= PADDLE_STEP + adj; } else { y1 = model.yMin; y2 = model.yMin + H; } } public void moveTo(float y) { y1 = (model.yMax - H) * y; y2 = (model.yMax * y + H *(1 - y)); } } class Ball { float x = model.cx, y = model.cy, z = model.cz; int xDir = 1, yDir = 1; int c = 0; public boolean contains(LXPoint p) { return sqrt(sq(p.x - ball.x) + sq(p.y - y) + sq(p.z - z)) < R; } public boolean step() { ++c; if (c > 360) c = 0; // Collision with floor/ceiling if (y + R > model.yMax || y - R < model.yMin) ball.yDir *= -1; // Collision with right wall if (x + R > model.xMax) { // Check if paddle is here if (y < right.y2 && y > right.y1) xDir *= -1; else return false; } // Collision with left wall if (x - R < model.xMin) { // Check if paddle is here if (y < left.y2 && y > left.y1) xDir *= -1; else return false; } x += xDir + xDir * 9 * speed.getValuef(); y += yDir + yDir * 9 * speed.getValuef(); return true; } } public boolean noteOn(Note note) { switch (note.getPitch()) { case 49: // W -> left paddle up left.moveUp(); break; case 50: // S -> left paddle down left.moveDown(); break; case 61: // O -> right paddle up right.moveUp(); break; case 62: // L -> right paddle down right.moveDown(); break; } return true; } public AKPong(LX lx) { super(lx); addParameter(speed); addParameter(leftKnob); addParameter(rightKnob); } public void run(double deltsMs) { float newLeft = leftKnob.getValuef(); float newRight = rightKnob.getValuef(); if (newLeft != oldLeft) { left.moveTo(newLeft); oldLeft = newLeft; } if (newRight != oldRight) { right.moveTo(newRight); oldRight = newRight; } if (! ball.step()) ball = new Ball(); for (LXPoint p : model.points) { if (ball.contains(p)) colors[p.index] = lx.hsb(ball.c, 100, 100); else if (left.contains(p)) colors[p.index] = lx.hsb(0, 0, 100); else if (right.contains(p)) colors[p.index] = lx.hsb(0, 0, 100); else colors[p.index] = 0; } } } /////////////////////////////////////////////////////////////////////////////// /************************************************************** * WORKS IN PROGRESS **************************************************************/ class AKInvader extends SCPattern { private final SawLFO h = new SawLFO(0, 1, 5000); public AKInvader(LX lx) { super(lx); addModulator(h).trigger(); } public void run(double deltaMs) { color c = lx.hsb(h.getValuef() * 360, 100, 100); int nTowers = model.towers.size(); int tower = nTowers / 2; // tower 0 for (int cube = 1; cube <= 3; ++cube) for (LXPoint p : model.towers.get(tower).cubes.get(cube).points) colors[p.index] = c; // tower 1 ++tower; for (int cube = 2; cube <= 3; ++cube) for (LXPoint p : model.towers.get(tower).cubes.get(cube).points) colors[p.index] = c; // for (LXPoint p : model.towers.get(tower).cubes.get(5).points) // colors[p.index] = c; // tower 2 ++tower; for (int cube = 1; cube <= 5; ++cube) for (LXPoint p : model.towers.get(tower).cubes.get(cube).points) colors[p.index] = c; // tower 3 ++tower; for (LXPoint p : model.towers.get(tower).cubes.get(0).points) colors[p.index] = c; for (int cube = 2; cube <= 3; ++cube) for (LXPoint p : model.towers.get(tower).cubes.get(cube).points) colors[p.index] = c; for (LXPoint p : model.towers.get(tower).cubes.get(5).points) colors[p.index] = c; // tower 4 ++tower; for (int cube = 2; cube <= 5; ++cube) for (LXPoint p : model.towers.get(tower).cubes.get(cube).points) colors[p.index] = c; // tower 5 ++tower; for (LXPoint p : model.towers.get(tower).cubes.get(0).points) colors[p.index] = c; for (int cube = 2; cube <= 3; ++cube) for (LXPoint p : model.towers.get(tower).cubes.get(cube).points) colors[p.index] = c; for (LXPoint p : model.towers.get(tower).cubes.get(5).points) colors[p.index] = c; // tower 6 ++tower; for (int cube = 1; cube <= 5; ++cube) for (LXPoint p : model.towers.get(tower).cubes.get(cube).points) colors[p.index] = c; // tower 7 ++tower; for (int cube = 2; cube <= 3; ++cube) for (LXPoint p : model.towers.get(tower).cubes.get(cube).points) colors[p.index] = c; // for (LXPoint p : model.towers.get(tower).cubes.get(5).points) // colors[p.index] = c; // tower 8 ++tower; for (int cube = 1; cube <= 3; ++cube) for (LXPoint p : model.towers.get(tower).cubes.get(cube).points) colors[p.index] = c; } } class AKTetris extends SCPattern { // Movement increments private final float STEP_Y = 1; private final float STEP_X = 10; // Block dimensions private final float D = 10; private Shape shape = new Box(); class Block { float x, y; // Block position, lower left corner public Block(float x, float y) { this.x = x; this.y = y; } } abstract class Shape { List blocks; // Blocks comprising this shape float x, y; // Shape position, lower left corner float h, w; // Effective Shape dimensions color c; public boolean contains(LXPoint p) { for (Block b : blocks) if (p.x > b.x && p.x < b.x + D && p.y > b.y && p.y < b.y + D) return true; return false; } public void dropDown(float inc) { for (Block b : blocks) b.y -= inc; y -= inc; } public void moveLeft(float inc) { for (Block b : blocks) b.x -= inc; x -= inc; } public void moveRight(float inc) { for (Block b : blocks) b.x += inc; x += inc; } } class Box extends Shape { public Box() { /** * [2][3] * [0][1] * red */ blocks = new LinkedList(); blocks.add(new Block(model.cx - D, model.yMax)); blocks.add(new Block(model.cx, model.yMax)); blocks.add(new Block(model.cx - D, model.yMax + D)); blocks.add(new Block(model.cx, model.yMax + D)); w = h = 2 * D; c = lx.hsb(0, 100, 100); x = model.cx - w / 2; y = model.yMax; } } public AKTetris(LX lx) { super(lx); } public boolean noteOn(Note note) { switch (note.getPitch()) { case 48: // A -> left shape.moveLeft(STEP_X); break; case 52: // D -> right shape.moveRight(STEP_X); break; } return true; } public void run(double deltaMs) { for (LXPoint p : model.points) { if (shape.contains(p)) colors[p.index] = shape.c; else colors[p.index] = 0; } if (shape.y > model.yMin) shape.dropDown(STEP_Y); } } class AKMatrix extends SCPattern { private List towerStrips = new ArrayList(0); class TowerStrip { List points = new ArrayList(0); } class DXPoint { LXPoint left, right; public DXPoint(LXPoint left, LXPoint right) { this.left = left; this.right = right; } } public AKMatrix(LX lx) { super(lx); // for (Tower t : model.towers) { Tower t = model.towers.get(0); for (int i = 0; i < 4; ++i) towerStrips.add(new TowerStrip()); // int i = 0; // for (Strip s : t.strips) { for (int i = 1; i <= 13; i += 2) { Strip s = t.strips.get(i); { for (LXPoint p : s.points) colors[p.index] = lx.hsb(80 * (i % 4), 100, 100); } } // ++i; } } } public void run(double deltaMs) { } } class AKEgg extends SCPattern { private final SinLFO xRadius = new SinLFO(0.01, 1, 1500); private final SinLFO yRadius = new SinLFO(0.01, 1, 2000); private final SinLFO zRadius = new SinLFO(0.01, 1, 2500); private LXPoint center; private float t; private final float X = model.xMax / 2; private final float Y = model.yMax / 2; private final float Z = model.zMax / 2; public AKEgg(LX lx) { super(lx); addModulator(xRadius).trigger(); addModulator(yRadius).trigger(); addModulator(zRadius).trigger(); center = new LXPoint(model.cx, model.cy, model.cz); t = 10; } public void run(double deltaMs) { for (LXPoint p : model.points) { float v = sqrt(sq(p.x - center.x) + sq(p.y - center.y) + sq(p.z - center.z)); float r = sqrt(sq(xRadius.getValuef() * X) + sq(yRadius.getValuef() * Y) + sq(zRadius.getValuef() * Z)); if (v > r - t && v < r) colors[p.index] = lx.hsb(0, 0, 100); else colors[p.index] = 0; } } } class AKCubes extends SCPattern { private Cube cube; private int sec; public AKCubes(LX lx) { super(lx); cube = model.cubes.get((int) random(model.cubes.size())); sec = 0; } public void run(double deltaMs) { sec += deltaMs; if (sec >= 1000) { for (LXPoint p : cube.points) colors[p.index] = 0; cube = model.cubes.get((int) random(model.cubes.size())); sec = 0; } for (LXPoint p : cube.points) colors[p.index] = lx.hsb(0, 0, 100); } } class AKSpiral extends SCPattern { private int ms; public AKSpiral(LX lx) { super(lx); ms = 0; } public void run(double deltaMs) { // colors[new LXPoint(model.cx, model.cy, model.cz).index] = lx.hsb(0, 0, 100); } } class AKSpace extends SCPattern { private LinkedList stars; class Star { // Current coordinates float x, y, z; // Ending coordinates // final float xEnd, yEnd, zEnd; // Radius final float r; // Speed float xInc, yInc, zInc; Star() { // Set radius this.r = 10; // Set starting coords at center this.reset(); } public void reset() { this.x = model.cx; this.y = model.cy; this.z = model.zMax + this.r; // Direction of movement float angle = random(0, TWO_PI); // Calculate speed of travel this.xInc = cos(angle); this.yInc = sin(angle); // Star must cover full z range in the time it takes to cover dist this.zInc = this.z / min(abs(model.xMax * cos(angle)), abs(model.yMax * sin(angle))); } public void increment() { this.x += this.xInc; this.y += this.yInc; this.z -= this.zInc; } public boolean outOfBounds() { return (this.x > model.xMax || this.x < model.xMin || this.y > model.yMax || this.y < model.yMin); } } public AKSpace(LX lx) { super(lx); stars = new LinkedList(); for (int i = 0; i < 50; ++i) stars.add(new Star()); } public void run(double deltaMs) { for (LXPoint p : model.points) colors[p.index] = 0; for (Star star : stars) { if (star.x > model.xMax || star.x < model.xMin || star.y > model.yMax || star.y < model.yMin) star.reset(); else { star.x += star.xInc; star.y += star.yInc; star.z -= star.zInc; } // Draw stars on model for (LXPoint p : model.points) { // Check if point falls within star if (sqrt(sq(p.x - star.x) + sq(p.y - star.y) + sq(p.z - star.z)) <= star.r) colors[p.index] = lx.hsb(0, 0, 100); } } } }