Search code examples
javaarrayslibgdx

Filling an array with random vector2's in libGdx


I was trying to fill the array "stars" with random vector2's, when I had a problem while testing two apparently similar codes.

Head

Array<Vector2> stars;
int numStars;

First Code

public void initStars() {

    int a = 100;
    int b = 120;
    numStars = (int) (a * b * 0.01f);
    stars = new Array<Vector2>(numStars);
    Random rand = new Random();
    Vector2 star = new Vector2();

    for (int i = 0 ;i <numStars ;i++){
        star.set(rand.nextInt(a),rand.nextInt(b));
        stars.add(star);           
    }
}

Second Code

public void initStars() {

    int a = 100;
    int b = 120;
    numStars = (int) (a * b * 0.01f);
    stars = new Array<Vector2>(numStars);
    Random rand = new Random();

    for (int i = 0 ;i <numStars ;i++){
        Vector2 star = new Vector2();
        star.set(rand.nextInt(a),rand.nextInt(b));
        stars.add(star);           
    }
}

The first didn't work, just fill the array with the last random vector generated in the loop, ie. all vectors in the array were equal, the second worked perfectly, my question is, why this happens, if the two codes are apparently equivalent.


Solution

  • The first segment of code couldn't possibly work. Take a closer look:

    Vector2 star = new Vector2();
    
    for (int i = 0 ;i <numStars ;i++){
        star.set(rand.nextInt(a),rand.nextInt(b));
        stars.add(star);           
    }
    

    You create the vector ONCE, and then keep assigning it new coordinates, then add it to the collection. When you call set(), you're setting the value of the same vector (because you're still referencing the same vector).

    The result is that you store the same vector in the collection numStars times, which is exactly what you notice.

    Maybe to make this more concrete, what you're creating in the first scenario is essentially this:

    stars = [starA, starA, starA, ..., starA]
    

    While the second one is this:

    stars = [starA, starB, starC, ..., starZ]
    

    If you call starA.set(), in the first case, you're not only modifying the star you're adding; you're modifying every star you put in before it (because they are the same star!).

    Hope this helps.