i made a NoGame using PVector
try it and see how the movement looks
( for me it look very natural, i trained air- / gun / pistol when i was young )
// https://discourse.processing.org/t/bug-with-arraylist/5949
// 11/2018 kll / my first game ever, good its not really a game
// make a arraylist of pvector points
// calc shortest distance to the next target, aim, fire + remove the point from array
int idt, pmax = 10;
ArrayList<PVector> points = new ArrayList<PVector>(); // list of points
PVector target = new PVector(0, 0); // position of cross line
boolean theend = false, shoot = false;
int k = 0, kmax = 30; //firing circles
float tdist, newdist, speedf = 0.04; // speed factor multiplied with distance gives realistic targeting movement
void setup() {
size( 300, 300);
for (int i = 0; i < pmax; i++) points.add(new PVector(random(-width/2, width/2), random(-height/2, height/2)));
//for ( PVector p : points ) println(p);
println("targets: "+points.size());
}
void draw_lines() {
stroke(200, 0, 0);
line(target.x, -height/2, target.x, height/2);
line(-width/2, target.y, width/2, target.y);
}
void draw_points() {
for (int i = 0; i < points.size(); i++) {
if ( i == idt ) stroke(200, 0, 0);
else noStroke();
fill(0, 200, 0);
ellipse(points.get(i).x, points.get(i).y, 8, 8);
}
}
int get_nearest() {
int idx = -1; // init to not found
tdist = width; // init to max
for (int i = 0; i < points.size(); i++) {
newdist = dist(points.get(i).x, points.get(i).y, target.x, target.y);
if ( newdist < tdist ) {
tdist = newdist;
idx = i;
}
}
return idx; // give index of nearest target
}
void aim() {
if ( idt > -1 ) {
PVector waytotarget = points.get(idt).copy();
waytotarget.sub(target);
if ( waytotarget.mag() > 0.5 ) { // thats close enough
waytotarget.setMag(waytotarget.mag()*speedf); // calc faster to short step in that direction
target = target.add(waytotarget); // change target
} else {
if ( !shoot ) println("shoot at "+idt); // only print
shoot = true;
points.remove(idt);
}
} else {
println("i win, but now i am alone!");
theend = true;
}
}
void fire() { // only if shoot = true
fill(200, 100, 0);
stroke(255, 0, 0);
strokeWeight(3);
ellipse(target.x, target.y, 2*k, 2*k); // growing red circle
strokeWeight(1);
k++;
if ( k >= kmax ) {
shoot = false;
k = 0;
}
}
void show_end() {
fill(0, 200, 0);
rect(-50, -25, 100, 40);
fill(200, 0, 0);
text(" I WIN ! ", -20, 0); // well, what a wonder if you play alone and targets not move
}
void draw() {
background(200, 200, 0);
translate(width/2, height/2);
if ( !theend ) {
draw_lines(); // cross lines
draw_points(); // all points fix pos, same size / red stroke for next target
idt = get_nearest(); // next ( nearest ) target
if ( !shoot ) aim(); // not walk while firing
else fire(); // some show / red circles
} else show_end(); // all over, no play again button
}
and a other example for “easing”