How to figure out which object is closest to a moving origin point

Let’s say I’m building a project. Just picture Galaga in your head. The ship you play as shoots missiles. What I’m trying to do here is to program the missiles to fly toward the nearest enemy ship along the x axis (y axis progresses no matter what).

The enemy class is in an array, I’ve got loops set up, etc… I just need to know how to logically engineer this concept.

Anyone have any insight?

1 Like

sorry

no idea.

that one might be close to your question:

// 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
}

autoshooter

1 Like

This is the behavior used in “flocking” – covered in the Nature of Code and Coding Train, for example – first find closest, then follow.

“Find the closest” with distance. A trick is that you can compute the squared distance (don’t need to take square roots). If you don’t care about the closest target, only the closest in x, then you can just take the absolute difference if xs.

For “move towards”, you can either increment or you can use lerp() – so the distant steering will be more dramatic.

1 Like