Switch to threaded mode by default, run engine at 120FPS
[SugarCubes.git] / AntonK.pde
1 /**************************************************************
2 * WORKING PATTERNS
3 **************************************************************/
4 import java.util.List;
5 import java.util.LinkedList;
6 class AKPong extends SCPattern
7 {
8 private final BasicParameter speed = new BasicParameter("Speed", 0);
9 private final BasicParameter leftKnob = new BasicParameter("Left", 0.5);
10 private final BasicParameter rightKnob = new BasicParameter("Right", 0.5);
11 private final float R = 20;
12 private final float W = 20;
13 private final float H = 80;
14 private final float PADDLE_STEP = 5;
15 private float oldLeft = leftKnob.getValuef();
16 private float oldRight = rightKnob.getValuef();
17
18 private Paddle left = new Paddle(model.xMin, model.cy - H / 2, model.xMin + W, model.cy + H / 2);
19 private Paddle right = new Paddle(model.xMax - W, model.cy - H / 2, model.xMax, model.cy + H / 2);
20 private Ball ball = new Ball();
21
22 class Paddle
23 {
24 float x1, y1, x2, y2;
25 public Paddle(float x1, float y1, float x2, float y2)
26 { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; }
27 public boolean contains(LXPoint p)
28 { return p.x > x1 && p.x < x2 && p.y > y1 && p.y < y2; }
29 public void moveUp()
30 {
31 float adj = 9 * speed.getValuef();
32 if (y2 + PADDLE_STEP < model.yMax)
33 {
34 y1 += PADDLE_STEP + adj;
35 y2 += PADDLE_STEP + adj;
36 }
37 else
38 {
39 y1 = model.yMax - H;
40 y2 = model.yMax;
41 }
42 }
43 public void moveDown()
44 {
45 float adj = 15 * speed.getValuef();
46 if (y2 - PADDLE_STEP > model.yMin)
47 {
48 y1 -= PADDLE_STEP + adj;
49 y2 -= PADDLE_STEP + adj;
50 }
51 else
52 {
53 y1 = model.yMin;
54 y2 = model.yMin + H;
55 }
56 }
57
58 public void moveTo(float y)
59 {
60 y1 = (model.yMax - H) * y;
61 y2 = (model.yMax * y + H *(1 - y));
62 }
63 }
64
65 class Ball
66 {
67 float x = model.cx, y = model.cy, z = model.cz;
68 int xDir = 1, yDir = 1;
69 int c = 0;
70 public boolean contains(LXPoint p)
71 { return sqrt(sq(p.x - ball.x) + sq(p.y - y) + sq(p.z - z)) < R; }
72 public boolean step()
73 {
74 ++c;
75 if (c > 360)
76 c = 0;
77
78 // Collision with floor/ceiling
79 if (y + R > model.yMax || y - R < model.yMin)
80 ball.yDir *= -1;
81 // Collision with right wall
82 if (x + R > model.xMax)
83 {
84 // Check if paddle is here
85 if (y < right.y2 && y > right.y1)
86 xDir *= -1;
87 else
88 return false;
89 }
90 // Collision with left wall
91 if (x - R < model.xMin)
92 {
93 // Check if paddle is here
94 if (y < left.y2 && y > left.y1)
95 xDir *= -1;
96 else
97 return false;
98 }
99 x += xDir + xDir * 9 * speed.getValuef();
100 y += yDir + yDir * 9 * speed.getValuef();
101 return true;
102 }
103 }
104
105 public boolean noteOn(Note note)
106 {
107 switch (note.getPitch())
108 {
109 case 49: // W -> left paddle up
110 left.moveUp();
111 break;
112 case 50: // S -> left paddle down
113 left.moveDown();
114 break;
115 case 61: // O -> right paddle up
116 right.moveUp();
117 break;
118 case 62: // L -> right paddle down
119 right.moveDown();
120 break;
121 }
122 return true;
123 }
124
125 public AKPong(LX lx)
126 {
127 super(lx);
128 addParameter(speed);
129 addParameter(leftKnob);
130 addParameter(rightKnob);
131 }
132
133 public void run(double deltsMs)
134 {
135 float newLeft = leftKnob.getValuef();
136 float newRight = rightKnob.getValuef();
137
138 if (newLeft != oldLeft)
139 {
140 left.moveTo(newLeft);
141 oldLeft = newLeft;
142 }
143 if (newRight != oldRight)
144 {
145 right.moveTo(newRight);
146 oldRight = newRight;
147 }
148 if (! ball.step())
149 ball = new Ball();
150 for (LXPoint p : model.points)
151 {
152 if (ball.contains(p))
153 colors[p.index] = lx.hsb(ball.c, 100, 100);
154 else if (left.contains(p))
155 colors[p.index] = lx.hsb(0, 0, 100);
156 else if (right.contains(p))
157 colors[p.index] = lx.hsb(0, 0, 100);
158 else
159 colors[p.index] = 0;
160 }
161 }
162 }
163
164
165 ///////////////////////////////////////////////////////////////////////////////
166
167 /**************************************************************
168 * WORKS IN PROGRESS
169 **************************************************************/
170
171 class AKInvader extends SCPattern
172 {
173 private final SawLFO h = new SawLFO(0, 1, 5000);
174 public AKInvader(LX lx)
175 {
176 super(lx);
177 addModulator(h).trigger();
178 }
179
180 public void run(double deltaMs)
181 {
182 color c = lx.hsb(h.getValuef() * 360, 100, 100);
183 int nTowers = model.towers.size();
184 int tower = nTowers / 2;
185 // tower 0
186 for (int cube = 1; cube <= 3; ++cube)
187 for (LXPoint p : model.towers.get(tower).cubes.get(cube).points)
188 colors[p.index] = c;
189 // tower 1
190 ++tower;
191 for (int cube = 2; cube <= 3; ++cube)
192 for (LXPoint p : model.towers.get(tower).cubes.get(cube).points)
193 colors[p.index] = c;
194 // for (LXPoint p : model.towers.get(tower).cubes.get(5).points)
195 // colors[p.index] = c;
196 // tower 2
197 ++tower;
198 for (int cube = 1; cube <= 5; ++cube)
199 for (LXPoint p : model.towers.get(tower).cubes.get(cube).points)
200 colors[p.index] = c;
201 // tower 3
202 ++tower;
203 for (LXPoint p : model.towers.get(tower).cubes.get(0).points)
204 colors[p.index] = c;
205 for (int cube = 2; cube <= 3; ++cube)
206 for (LXPoint p : model.towers.get(tower).cubes.get(cube).points)
207 colors[p.index] = c;
208 for (LXPoint p : model.towers.get(tower).cubes.get(5).points)
209 colors[p.index] = c;
210 // tower 4
211 ++tower;
212 for (int cube = 2; cube <= 5; ++cube)
213 for (LXPoint p : model.towers.get(tower).cubes.get(cube).points)
214 colors[p.index] = c;
215 // tower 5
216 ++tower;
217 for (LXPoint p : model.towers.get(tower).cubes.get(0).points)
218 colors[p.index] = c;
219 for (int cube = 2; cube <= 3; ++cube)
220 for (LXPoint p : model.towers.get(tower).cubes.get(cube).points)
221 colors[p.index] = c;
222 for (LXPoint p : model.towers.get(tower).cubes.get(5).points)
223 colors[p.index] = c;
224 // tower 6
225 ++tower;
226 for (int cube = 1; cube <= 5; ++cube)
227 for (LXPoint p : model.towers.get(tower).cubes.get(cube).points)
228 colors[p.index] = c;
229 // tower 7
230 ++tower;
231 for (int cube = 2; cube <= 3; ++cube)
232 for (LXPoint p : model.towers.get(tower).cubes.get(cube).points)
233 colors[p.index] = c;
234 // for (LXPoint p : model.towers.get(tower).cubes.get(5).points)
235 // colors[p.index] = c;
236 // tower 8
237 ++tower;
238 for (int cube = 1; cube <= 3; ++cube)
239 for (LXPoint p : model.towers.get(tower).cubes.get(cube).points)
240 colors[p.index] = c;
241 }
242 }
243
244
245 class AKTetris extends SCPattern
246 {
247 // Movement increments
248 private final float STEP_Y = 1;
249 private final float STEP_X = 10;
250 // Block dimensions
251 private final float D = 10;
252
253 private Shape shape = new Box();
254
255 class Block
256 {
257 float x, y; // Block position, lower left corner
258 public Block(float x, float y)
259 {
260 this.x = x;
261 this.y = y;
262 }
263 }
264
265 abstract class Shape
266 {
267 List<Block> blocks; // Blocks comprising this shape
268 float x, y; // Shape position, lower left corner
269 float h, w; // Effective Shape dimensions
270 color c;
271
272 public boolean contains(LXPoint p)
273 {
274 for (Block b : blocks)
275 if (p.x > b.x && p.x < b.x + D && p.y > b.y && p.y < b.y + D)
276 return true;
277 return false;
278 }
279
280 public void dropDown(float inc)
281 {
282 for (Block b : blocks)
283 b.y -= inc;
284 y -= inc;
285 }
286
287 public void moveLeft(float inc)
288 {
289 for (Block b : blocks)
290 b.x -= inc;
291 x -= inc;
292 }
293
294 public void moveRight(float inc)
295 {
296 for (Block b : blocks)
297 b.x += inc;
298 x += inc;
299 }
300 }
301
302 class Box extends Shape
303 {
304 public Box()
305 {
306 /**
307 * [2][3]
308 * [0][1]
309 * red
310 */
311 blocks = new LinkedList<Block>();
312 blocks.add(new Block(model.cx - D, model.yMax));
313 blocks.add(new Block(model.cx, model.yMax));
314 blocks.add(new Block(model.cx - D, model.yMax + D));
315 blocks.add(new Block(model.cx, model.yMax + D));
316 w = h = 2 * D;
317 c = lx.hsb(0, 100, 100);
318 x = model.cx - w / 2;
319 y = model.yMax;
320 }
321 }
322
323 public AKTetris(LX lx)
324 {
325 super(lx);
326 }
327
328 public boolean noteOn(Note note)
329 {
330 switch (note.getPitch())
331 {
332 case 48: // A -> left
333 shape.moveLeft(STEP_X);
334 break;
335 case 52: // D -> right
336 shape.moveRight(STEP_X);
337 break;
338 }
339 return true;
340 }
341
342 public void run(double deltaMs)
343 {
344 for (LXPoint p : model.points)
345 {
346 if (shape.contains(p))
347 colors[p.index] = shape.c;
348 else
349 colors[p.index] = 0;
350 }
351 if (shape.y > model.yMin)
352 shape.dropDown(STEP_Y);
353 }
354 }
355
356
357 class AKMatrix extends SCPattern
358 {
359 private List<TowerStrip> towerStrips = new ArrayList<TowerStrip>(0);
360
361 class TowerStrip
362 {
363 List<LXPoint> points = new ArrayList<LXPoint>(0);
364 }
365
366 class DXPoint
367 {
368 LXPoint left, right;
369 public DXPoint(LXPoint left, LXPoint right)
370 {
371 this.left = left;
372 this.right = right;
373 }
374 }
375
376 public AKMatrix(LX lx)
377 {
378 super(lx);
379 // for (Tower t : model.towers)
380 {
381 Tower t = model.towers.get(0);
382 for (int i = 0; i < 4; ++i)
383 towerStrips.add(new TowerStrip());
384
385 // int i = 0;
386 // for (Strip s : t.strips)
387 {
388 for (int i = 1; i <= 13; i += 2)
389 {
390 Strip s = t.strips.get(i);
391 {
392 for (LXPoint p : s.points)
393 colors[p.index] = lx.hsb(80 * (i % 4), 100, 100);
394 }
395 }
396 // ++i;
397 }
398 }
399 }
400
401 public void run(double deltaMs)
402 {
403 }
404 }
405
406
407 class AKEgg extends SCPattern
408 {
409 private final SinLFO xRadius = new SinLFO(0.01, 1, 1500);
410 private final SinLFO yRadius = new SinLFO(0.01, 1, 2000);
411 private final SinLFO zRadius = new SinLFO(0.01, 1, 2500);
412
413 private LXPoint center;
414 private float t;
415 private final float X = model.xMax / 2;
416 private final float Y = model.yMax / 2;
417 private final float Z = model.zMax / 2;
418
419 public AKEgg(LX lx)
420 {
421 super(lx);
422 addModulator(xRadius).trigger();
423 addModulator(yRadius).trigger();
424 addModulator(zRadius).trigger();
425
426 center = new LXPoint(model.cx, model.cy, model.cz);
427 t = 10;
428 }
429
430 public void run(double deltaMs)
431 {
432 for (LXPoint p : model.points)
433 {
434 float v = sqrt(sq(p.x - center.x) + sq(p.y - center.y) + sq(p.z - center.z));
435 float r = sqrt(sq(xRadius.getValuef() * X) + sq(yRadius.getValuef() * Y) + sq(zRadius.getValuef() * Z));
436 if (v > r - t && v < r)
437 colors[p.index] = lx.hsb(0, 0, 100);
438 else
439 colors[p.index] = 0;
440 }
441 }
442 }
443
444
445 class AKCubes extends SCPattern
446 {
447 private Cube cube;
448 private int sec;
449
450 public AKCubes(LX lx)
451 {
452 super(lx);
453 cube = model.cubes.get((int) random(model.cubes.size()));
454 sec = 0;
455 }
456
457
458 public void run(double deltaMs)
459 {
460 sec += deltaMs;
461 if (sec >= 1000)
462 {
463 for (LXPoint p : cube.points)
464 colors[p.index] = 0;
465 cube = model.cubes.get((int) random(model.cubes.size()));
466 sec = 0;
467 }
468 for (LXPoint p : cube.points)
469 colors[p.index] = lx.hsb(0, 0, 100);
470 }
471 }
472
473
474 class AKSpiral extends SCPattern
475 {
476 private int ms;
477 public AKSpiral(LX lx)
478 {
479 super(lx);
480 ms = 0;
481 }
482
483 public void run(double deltaMs)
484 {
485 // colors[new LXPoint(model.cx, model.cy, model.cz).index] = lx.hsb(0, 0, 100);
486 }
487 }
488
489
490 class AKSpace extends SCPattern
491 {
492 private LinkedList<Star> stars;
493
494 class Star
495 {
496 // Current coordinates
497 float x, y, z;
498 // Ending coordinates
499 // final float xEnd, yEnd, zEnd;
500 // Radius
501 final float r;
502 // Speed
503 float xInc, yInc, zInc;
504
505 Star()
506 {
507 // Set radius
508 this.r = 10;
509 // Set starting coords at center
510 this.reset();
511 }
512
513 public void reset()
514 {
515 this.x = model.cx;
516 this.y = model.cy;
517 this.z = model.zMax + this.r;
518
519 // Direction of movement
520 float angle = random(0, TWO_PI);
521 // Calculate speed of travel
522 this.xInc = cos(angle);
523 this.yInc = sin(angle);
524 // Star must cover full z range in the time it takes to cover dist
525 this.zInc = this.z / min(abs(model.xMax * cos(angle)), abs(model.yMax * sin(angle)));
526 }
527
528 public void increment()
529 {
530 this.x += this.xInc;
531 this.y += this.yInc;
532 this.z -= this.zInc;
533 }
534
535 public boolean outOfBounds()
536 {
537 return (this.x > model.xMax || this.x < model.xMin || this.y > model.yMax || this.y < model.yMin);
538 }
539 }
540
541 public AKSpace(LX lx)
542 {
543 super(lx);
544 stars = new LinkedList<Star>();
545 for (int i = 0; i < 50; ++i)
546 stars.add(new Star());
547 }
548
549 public void run(double deltaMs)
550 {
551 for (LXPoint p : model.points)
552 colors[p.index] = 0;
553
554 for (Star star : stars)
555 {
556 if (star.x > model.xMax || star.x < model.xMin || star.y > model.yMax || star.y < model.yMin)
557 star.reset();
558 else
559 {
560 star.x += star.xInc;
561 star.y += star.yInc;
562 star.z -= star.zInc;
563 }
564 // Draw stars on model
565 for (LXPoint p : model.points)
566 {
567 // Check if point falls within star
568 if (sqrt(sq(p.x - star.x) + sq(p.y - star.y) + sq(p.z - star.z)) <= star.r)
569 colors[p.index] = lx.hsb(0, 0, 100);
570 }
571 }
572 }
573 }