2013/06/29

vehicle seq (for SuperCollider)

var wd, width=500, run=true;
var dist, moveVehicle, stone, catchStones;
var pos=[5, 5], vec=[20, 20], vlim=50;
var turn=100, margin=80, accel=0.02, scope=200;
var num = 24;

stone = Array.fill(num, {|i|
 [0.8.rand+0.1*width, 0.8.rand+0.1*width]
});

catchStones = Array.fill(num, {0});

wd = Window("", Rect(50, 50, width, width));
wd.view.background = Color.black;
wd.alwaysOnTop = true;
wd.onClose = { run=false };
wd.front;

wd.drawFunc = {
 Pen.use {
  Pen.translate(pos[0], pos[1]);
  Pen.rotate(atan2(vec[1], vec[0]));
  Pen.fillColor = Color.white;
  Pen.moveTo(10@0);
  Pen.lineTo(-10@5);
  Pen.lineTo(-10@(-5));
  Pen.lineTo(10@0);
  Pen.fill;
 };

 stone.do {|e|
  Pen.use {
   Pen.fillColor = Color.white;
   Pen.addRect(
    Rect(e[0], e[1], 10, 10);
   );
   Pen.fill;
  };
 };

};

dist = {|ax, ay, bx, by|
 sqrt((bx-ax**2)+(by-ay**2));
};

moveVehicle = {
 var spd = dist.(0,0,vec[0],vec[1]);

 stone.do {|e, i|
  var dst = dist.(pos[0], pos[1], e[0], e[1]);

  if(dst < 50, {
   vec[0] = vec[0] - (e[0] - pos[0] / turn);
   vec[1] = vec[1] - (e[1] - pos[1] / turn);
  });

  if(dst < scope, {
   if(catchStones[i] != 1, {
    s.sendMsg(\s_new, \hoge, 100+i, 0, 0, \id, i);

    catchStones[i] = 1;
    },{
     var ro = atan2(vec[1], vec[0])+(pi/2);
     var xq = (sin(ro)*(e[0]-pos[0]))-(cos(ro)*(e[1]-pos[1]));
     var yq = (cos(ro)*(e[0]-pos[0]))+(sin(ro)*(e[1]-pos[1]));
     var pn = atan2(yq, xq)/pi;
     s.sendMsg(\n_set, 100+i, \amp, ((scope-dst)/scope)**2, \pan, pn);
   });

   },{
    if(catchStones[i] == 1, {
     s.sendMsg(\n_free, 100+i);
     catchStones[i] = 0;
    });
  });
 };

 if(spd > vlim, {
  vec[0] = vec[0] / 2;
  vec[1] = vec[1] / 2;
 });

 pos[0] = vec[0] * accel + pos[0];
 pos[1] = vec[1] * accel + pos[1];

 // torus world
 if(pos[0] < 0, {
  pos[0] = width;
  },{
   if(pos[0] > width, { pos[0] = 0 });
 });

 if(pos[1] < 0, {
  pos[1] = width;
  },{
   if(pos[1] > width, { pos[1] = 0 });
 });

 // repellent
 if(pos[0] < margin, {
  vec[0] = vec[0] - (0 - pos[0] / turn);
 });
 if(pos[0] > (width-margin), {
  vec[0] = vec[0] - (width - pos[0] / turn);
 });
 if(pos[1] < margin, {
  vec[1] = vec[1] - (0 - pos[1] / turn);
 });
 if(pos[1] > (width-margin), {
  vec[1] = vec[1] - (width - pos[1] / turn);
 });
};

SynthDef(\hoge, {|amp, pan, id|
 a = Mix.fill(3, {|n|
  b = midicps(n*7+id+48);
  SinOsc.ar(b, SinOsc.ar(b*3, 0, 0.7), 0.01);
 });
 Out.ar(50, a*amp);
 #w, x, y = PanB2.ar(a, pan);
 #d, e, f, g = DecodeB2.ar(4, w, x, y);
 #u, v = Rotate2.ar(d+e, d+e, pan/2)*amp;
 Out.ar(0, [v, u]);
}).store;

SynthDef(\moge, {
 i = InFeedback.ar(50);
 #x,y = LPF.ar(i!2, 400, 2);
 r = FreeVerb2.ar(x, y, 1, 0.9);
 Out.ar(0, r);
}).play;

{
 while { run } {
  moveVehicle.();
  wd.refresh;
  0.01.wait;
 }
}.fork(AppClock)

AddThis