# Finding distances between sprites in an array

i'm new to java and was hoping if anyone can help me out. So my game has meteors which spawns off screen and sometimes as they spawn, they overlap each other which I don't want. I want them to spawn from a certain distance from each other.

From pseudo code I know what I want which is to find the centre point of sprite, find other meteors on screen and calculate the distance and then spawn from a certain distance from each other. I know the distance to point formula (distance = Math.sqrt(Math.pow(x2 - x1, 2) + (Math.pow(y2 - y1, 2)));), but how do I do that within an array. Here is my code so far:

Meteor Class

public class Meteors {
private Texture bigMeteor;
private Vector2 posBigMeteor;
private Random yrand;

//Constructor
public Meteors(float x){
bigMeteor = new Texture("meteor.png");
yrand = new Random();

//Spawn location of meteor
posBigMeteor = new Vector2(x, yrand.nextInt(AstroDemo.HEIGHT/2 - bigMeteor.getHeight()));
}

public Texture getBigMeteor() {
return bigMeteor;
}

public Vector2 getPosBigMeteor() {
return posBigMeteor;
}

public void reposition(float x){
posBigMeteor.set(x, yrand.nextInt(AstroDemo.HEIGHT/2 - bigMeteor.getHeight()));
}
}


Playstate Class

public class PlayState extends State {
//Total meteor count on screen
private static final int METEOR_COUNT = 8;

private Naught naught;
private Texture bg;
private Random xrand;
private Array <Meteors> meteors;

public PlayState(GameStateManager gsm) {
super(gsm);
//Starting co-ordinates of main character (Naught)
naught = new Naught(50, 100);
//Setting viewport of the camera
cam.setToOrtho(false, AstroDemo.WIDTH/2, AstroDemo.HEIGHT/2);
bg = new Texture("bg.png");
xrand = new Random();

meteors = new Array <Meteors>();

//Spawn meteors randomly off screen
for (int i = 1; i <= METEOR_COUNT; i++){
}
}

@Override
protected void handleInput() {
//If screen/mouse is held
if(Gdx.input.isTouched()){
//Main Character jumps/flys
naught.jump();
}
}

@Override
public void update(float dt) {
handleInput();
naught.update(dt);
//If meteors are left side of the screen, re-position to the right side of the screen
for(Meteors meteor : meteors){
if (cam.position.x - (cam.viewportWidth/2) > meteor.getPosBigMeteor().x + meteor.getBigMeteor().getWidth()){
meteor.reposition(meteor.getPosBigMeteor().x + (AstroDemo.WIDTH/2 + 20 + (xrand.nextInt(300))));
}
}
cam.position.x = naught.getPosition().x + 80;

cam.update();
}

@Override
public void render(SpriteBatch sb) {
//Adjust the spritebatch for co-ordinate system in relation to camera
sb.setProjectionMatrix(cam.combined);
sb.begin();
//Draw background where the camera is
sb.draw(bg, cam.position.x - (cam.viewportWidth/2), 0);
sb.draw(naught.getTexture(), naught.getPosition().x, naught.getPosition().y);
for (Meteors meteor : meteors) {
sb.draw(meteor.getBigMeteor(), meteor.getPosBigMeteor().x, meteor.getPosBigMeteor().y);
}
sb.end();
}

@Override
public void dispose() {

}
}

• It's not clear to me what kind of help you need here. Why would applying the distance formula to objects selected from an array be different than applying the formula to anything else? You seem to understand for-loops, so I'm not sure what the step you're missing might be. – DMGregory Jan 22 '17 at 0:32
• If you are going to spawn only 8 meteors one time (as your code do) you can put an array of random x distances to the constructor, where minDistance (between meteors) would be meteorWidth and maxDistance would be based on cordinates of previous meteor and screenWidth. – Andrei Yusupau Jan 22 '17 at 17:08

So you want to generate meteor and you don't want them to spawn at a location where they overlap. Plus, you want them to be spaced by a minimal amount.

In my opinion, you should not compute y positions that way. I'll do the y generation at the same time of x. I'll assume you build a meteor by x AND y positions.

I usually make a function for this. This code will do those things :

1. Make meteor at 0,0 location
2. Compute random x and y
3. Compute distance between x/y and already existing meteors
4. Compute new random x and y until distance between new meteor and already existing meteors is superior or equal to the minimal distance autorized between meteors
5. Set position of the meteor
6. Return the meteor

// This will create a meteor, and compute positions until they don't overlap with other meteors
private Meteors generateMeteor(int maxX, int maxY, float minDistanceBetweenMeteors)
{
// Make the meteor
Meteors meteor = new Meteor(0, 0) // You don't care at the moment

// Init positions
float x = rand.nextInt(maxX); // Your boundaries
float y = rand.nextInt(maxY); // Your boundaries

// Now you want to check if the min distance is good enough
float distance;
boolean minDistanceRespected = true; // The first meteor is always in respect of min distance

do
{
for (Meteors m : meteors)
{
// Compute distance between your new meteor and the existing ones
distance = Math.sqrt(Math.pow(m.getX() - x, 2) + (Math.pow(m.getY() - y, 2));

// Check if distance is good enough
if (distance < minDistanceBetweenMeteors)
{
minDistanceRespected = false;

// Compute positions again
x = rand.nextInt(maxX);
y = rand.nextInt(maxY);

break; // Don't need to check for others
}
else
{
minDistanceRespected = true;
}
}
} while (!minDistanceRespected);

// Reach this point means you finally get good positions
meteor.reposition(x, y); // Change your reposition method to actually take x and y as position (you compute a random y each time you set a new X, here we want to set both of them
}


To use :

 meteors.add(generateMeteor(maxX, maxY, minDistanceBetweenMeteors));