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