...and here is the code.
you need to include the font in the folder.
it is one of the standard fonts included in the processing examples
Quote://////////////////////////////////////////////
//"Static chaser"
//use TAB to generate chasers
//use WASDQE to move the target
///////////////////////////////////////////////
import processing.opengl.*;
//class init
target tg = new target(-100,-1,0);
grid gr = new grid(0,0,0);
ArrayList balls;
float cntz=0;
void setup() {
size(640, 480, OPENGL);
PFont font;
font = loadFont("CourierNew36.vlw");
textFont(font);
frameRate(60);
PVector Ppos = new PVector(10,10,10);
balls = new ArrayList();
balls.add(new ball(Ppos));
}
void draw() {
lights();
background(0);
text(balls.size(), 15, 60);
cntz++;
camera(250*sin(radians(cntz/10)), -150+mouseY, 250.0*cos(radians(cntz/10)), // eyeX, eyeY, eyeZ
0.0, 0.0, 0.0, // centerX, centerY, centerZ
0.0, 1.0, 0.0); // upX, upY, upZ
gr.update();
tg.update();
PVector Ptarget = new PVector(tg.x,tg.y,tg.z);
//dual "for loop"
//move every chaser closer to target
//move every chaser away from every other chaser
for(int i = balls.size() -1; i>=0; i--){
ball bo = (ball) balls.get(i);
bo.updatetarget(Ptarget);
for (int j = balls.size()-1; j>=0; j--){
if (i!=j){
ball bi = (ball) balls.get(j);
PVector Pother = new PVector(bi.pos.x,bi.pos.y,bi.pos.z);
bo.updateother(Pother);
/*stroke(80,80,158,10);
line(bo.pos.x,bo.pos.y,bo.pos.z,bi.pos.x,bi.pos.y,bi.pos.z);*/
}
}
bo.display();
}
}
public class ball{
PVector pos;
PVector target;
PVector other;
float pspeed;
float nspeed;
float csize = 3;
ball (PVector inpos){
pos = inpos;
}
void updatetarget(PVector intarget){
target = intarget;
PVector chaserToTarget = PVector.sub(target, pos);
//chaserToTarget.limit(pspeed);
pspeed = chaserToTarget.mag()/55;
chaserToTarget.normalize();
chaserToTarget.mult(pspeed);
pos.add(chaserToTarget);
}
void updateother(PVector inother){
other = inother;
PVector chaserToOther = PVector.sub(other, pos);
//chaserToOther.limit(nspeed);
nspeed = .2-20/chaserToOther.mag();
chaserToOther.normalize();
chaserToOther.mult(nspeed);
pos.add(chaserToOther);
}
void display(){
pushMatrix();
noStroke();
fill(255);
translate(pos.x,pos.y,pos.z);
box(csize);
popMatrix();
}
}
public class grid{
float x,y,z;
int i=0; //counter
int c = 0; //colorizer
grid(float inx, float iny, float inz) {
x = inx;
y = iny;
z = inz;
}
void update(){
for (i=-100; i<=100; i+=5){ //x-y
if (i<0) c = i/2;
else if (i>0) c = -i/2;
else c = 50;
stroke (255,255,255,50+c);
line(-100,i,0,100,i,0);
line(i,-100,0,i,100,0);
line(-100,0,i,100,0,i);
line(i,0,-100,i,0,100);
line(0,-100,i,0,100,i);
line(0,i,-100,0,i,100);
}
}
}
void keyPressed(){
if(key == TAB){
PVector Ppos = new PVector(0,0,0);
balls.add(new ball(Ppos));
}
}
public class target{
float x,y,z;
target(float inx, float iny, float inz) {
x = inx;
y = iny;
z = inz;
}
void update(){
if (keyPressed){
if ((key == 'W' )||( key == 'w')){
y-=5;
if (y<-100) y = -100;
}
if ((key == 'S' )||( key == 's')){
y+=5;
if (y>100) y = 100;
}
if ((key == 'A' )||( key == 'a')){
x-=5;
if (x<-100) x = -100;
}
if ((key == 'D' )||( key == 'd')){
x+=5;
if (x>100) x = 100;
}
if ((key == 'Q' )||( key == 'q')){
z+=5;
if (z>100) z = 100;
}
if ((key == 'E' )||( key == 'e')){
z-=5;
if (z<-100) z = -100;
}
}
pushMatrix();
noStroke();
fill(255,0,0,random(255));
translate(x,y,z);
box(3);
popMatrix();
/*stroke(255,0,0,80);
line(x,-100,0,x,100,0);//
line(-100,y,0,100,y,0);//
line(x,0,-100,x,0,100);//
line(-100,0,z,100,0,z);//
line(0,y,-100,0,y,100);//
line(0,-100,z,0,100,z);//
stroke(255,0,0,250);
line(x,y,z,x,y,0);
line(x,y,z,x,0,z);
line(x,y,z,0,y,z);*/
}
}