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)
