Regarding the initial moving-along-a-path question, one general approach is a list-based interpolation.
Here is an example. In setup, a path made of points is defined. In draw, the current path location is computed based on the clock. Then that location (0-1) is passed to the lerpVectors function to find the current point along the path.
// LerpVectorsSimplified
// 2019-04 Processing 3.4 - based on LerpVectorsExample by Jeremy Douglass
PVector vecs[];
PVector loc;
void setup() {
size(200, 200);
// mark path points
vecs = new PVector[4];
vecs[0] = new PVector(10, 10);
vecs[1] = new PVector(width-10, 10);
vecs[2] = new PVector(width-10, height-10);
vecs[3] = new PVector(10, height-10);
stroke(255,0,0);
fill(0,0,255);
}
void draw() {
background(255);
int time = millis()%4000; // a clock that counts up to 4000 and starts over
float sawtoothWave = map(time, 0, 3999, -1, 1); // from -1 to 1, then starts over
float triangleWave = abs(sawtoothWave); // bounces 0-1-0-1-0
loc = lerpVectors(triangleWave, vecs); // find our location in 2D path based on 0-1
ellipse(loc.x, loc.y, 50, 50); // draw at the location
}
// based on an amount, find the location along a path made of points
PVector lerpVectors(float amt, PVector... vecs) {
if(vecs.length==1){ return vecs[0]; }
float cunit = 1.0/(vecs.length-1);
return PVector.lerp(vecs[floor(amt / cunit)], vecs[ceil(amt / cunit)], amt%cunit/cunit);
}