/**
* Dynamic tracking with a delay. An illustration of how increasing delays
* make control difficult.
*
*
Try to keep the red ball inside the blue target, using the mouse.
*
*
The red ball has momentum and is subject to drag. It is, in effect,
* coupled to your mouse location by a spring, subject to a pipeline delay.
*
*
Initially the task is fairly easy. Use the keyboard
* to increase complexity of the task by changing the dynamics of the
* ball ( b and m), allowing the target to drift (t), and adding a delay between the
* mouse and ball control (d). You can toggle display of your delayed
* mouse location (s). You may need to click in the window to give
* it focus before the controls work.
*
*
Get a feel for it, then crank the delay and drift up to 5
* and see how you fare.
*
*
Draws on Processing's easing, keyboard and arraylist examples.
*
*
Tom Fiddaman, Ventana Systems, 2009
*/
float x=0;
float y=0;
float vx=0;
float vy=0;
float m=1;
float k=.05;
float b=1;
float g = .1;
float targetX, targetY;
float easing = 1;
color target = color(60,60,180);
color ball = color(200,30,30);
ArrayList mouseLocs;
int delaySize=1;
int wsize = 400;
float tx = wsize/2;
float ty = wsize/2;
float tdx =0;
float tdy=0;
int drift = 0; // target drift rate
float recenter = .05; // target recentering rate
float drag = .2; // target damping
PFont fontA;
TextControl delayBar;
TextControl driftBar;
TextControl showBar;
TextControl massBar;
TextControl dragBar;
void setup()
{
size(400, 400); // needs to be a # for export to size properly
smooth();
noStroke();
mouseLocs = new ArrayList();
for(int i=0;i Create Font
// to create a distributable bitmap font.
// For vector fonts, use the createFont() function.
fontA = loadFont("Tahoma-Bold-9.vlw");
// Set the font and its size (in units of pixels)
textFont(fontA, 9);
delayBar = new TextControl("d delay","d","_",10,0);
driftBar = new TextControl("t target drift","t","_",5,0);
showBar = new TextControl("s show delay","s","_",1,0);
dragBar = new TextControl("b drag","b","_",2,1);
massBar = new TextControl("m mass","m","_",2,2);
frameRate(30);
}
void draw()
{
background( 51 );
// controls
fill(200);
text(delayBar.textBar(),4,10);
text(driftBar.textBar(),4,22);
text(showBar.textBar(),4,34);
text(dragBar.textBar(),4,46);
text(massBar.textBar(),4,58);
// settings
delaySize = 1+delayBar.setting*5;
drift = driftBar.setting;
m = .1+massBar.setting/2;
b = .1+dragBar.setting/2;
// target
tdx = tdx+(random(drift)-drift/2)-drag*tdx;
tdy = tdy+(random(drift)-drift/2)-drag*tdy;
tx = tx + recenter*(wsize/2-tx) + tdx;
ty = ty + recenter*(wsize/2-ty) + tdy;
fill(target);
noStroke();
ellipse(tx,ty,33,33);
// ball
targetX = mouseX;
targetY = mouseY;
mouseLocs.add(new Location(targetX,targetY));
while (mouseLocs.size() > delaySize) {
mouseLocs.remove(0);
}
Location xy = (Location)mouseLocs.get(0);
float dx = xy.x-x;
float dy = xy.y-y;
if (showBar.setting == 1) {
stroke(ball);
noFill();
ellipse(xy.x, xy.y, 16, 16); }
/*
float r2 = pow((x-wsize/2),2)+pow((y-wsize/2),2);
float rx = (x-wsize/2);
float ry = (y-wsize/2);
*/
vx = vx+k*dx/m-b*m*vx;
vy = vy+k*dy/m-b*m*vy;
x += vx * easing;
y += vy * easing;
fill(ball);
ellipse(x, y, 16, 16);
}
void keyReleased() {
delayBar.increment(key);
driftBar.increment(key);
showBar.increment(key);
dragBar.increment(key);
massBar.increment(key);
}