0
\$\begingroup\$

I want to generate stars (actually a 2d vector) in the background. The player is moving left and right endlessly. When the player moves the stars, which aren't in sight anymore, should be deleted from the ArrayList to keep things small. But when the player turns back in the other direction again, the same star(coordinate) should be there again. But the random generator gets a different number, which is normal. How can I do something like lastInt() like I do with nextInt() ? Or what is the proper way to do something like this? Thank you very much.

\$\endgroup\$
  • \$\begingroup\$ How many stars do you plan to have on-screen at one time? How are you rendering your individual stars? Sprites or pixels? Can you show a screenshot of what you would like your starfield to look like? That might clear up some things so Menno or myself can help you better. \$\endgroup\$ – Fuzzy Logic Jul 26 '15 at 11:38
1
\$\begingroup\$

As Menno Gouw mentioned, you could use a noise function although you can actually use any PRNG. You will need to seed it every frame though, based off some predictable, relative value, such as the player position. If the player only moves horizontally, then this is simple. seed = player.x

I don't suggest a noise algorithm in this case, since the implementation is rudimentary and a noise function is relatively expensive for no real gain.

If the player moves in more than one direction then you will have to construct the seed value by combining the positions on each axis since most PRNG's only accept a single value for the seed. This is not very complicated either but I won't go into detail. If you need to generate a seed from a vector, then you may want to consider using a noise algorithm, though it is still overkill.

\$\endgroup\$
  • \$\begingroup\$ This may go in the right direction, thank you. But I think the way I determine when to delete and generate stars is still not working. Do you have an idea? \$\endgroup\$ – Kronos Jul 25 '15 at 21:47
  • \$\begingroup\$ There is a couple of ways to add/remove the stars. The most efficient is to use a starfield texture that is the size of the viewport. When the player moves, you scroll the stars on the texture, the part that scrolls off the texture is gone and will leave a gap on the opposite side. Eg. player moves right 1 pixel. Shift star texture left by 1 pixel, then regenerate the right-most column of pixels. A simpler way would be to store all stars in a fixed-length (important!) array and iterate all of them each frame. Remove any stars off-screen and for any empty indices, generate a new star (or not). \$\endgroup\$ – Fuzzy Logic Jul 25 '15 at 22:26
1
\$\begingroup\$

at the base of some perlin noise implememntatio there's a perturbation array

        private static int[] p = {151,160,137,91,90,15,
 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180};

and gradinet array

    float[] grad = new float[256];//used pseudo random generation form cooord (x) or (x,y) or (z,y,z) ...
//You must initialize it with float values in 0..1

given that we can generate a gradient for a point x,y:

  private float pseudoRandomFromPerm(int x, int y)
    {
        return grad[(x + p[y & 255]+Seed) % grad.GetLength(0)];
    }

after that perln noise does others (time consuming) thinks like interpolate a position fx , fy starting from x,y , and repeat the operation for a number n of octaves...

What I suggest is , instead of asking for a gradient for x,y ask for n (depending on star density) dx , dy (0..1 values) and set a star in x+dx*(scale) , y+dy*(scale)

enter image description here

you can ask , how can get n (0..1) values from X,Y? Add a costant value for each interrogation:

grad[(x + p[y & 255] + Seed  + 1) % grad.GetLength(0)]; //dx1
grad[(x + p[y & 255] + Seed  + 2) % grad.GetLength(0)]; //dy1
grad[(x + p[y & 255] + Seed  + 3) % grad.GetLength(0)]; //dx2
...n times
\$\endgroup\$
0
\$\begingroup\$

You need something like perlin or simplex noise. This will always generate the same noise based on position with a certain seed. Now you can add stars where the noise is a certain level.

Simplex and perlin noise always create the same noise based on location and seed. So if you would create a noise ranging from 0 to 255 you could generate a stars at a certain level of the noise. Both perlin and simplex is very versatile, there are some paremeters you can set and it generates values for you, you can use multiple noises on top of eachother. You will probably need to tweak these settings a lot to get the desired effect you want.

For example minecraft uses it for terrain height. You can use it for brighter and dimmer stars. If the noise of the first iteration is between 0-100 you check the noise of the 2nd iteration and where you get a specific value or two you generate a star. Then you run another noise to see if they are dim or bright.

Using this for each and every pixel of your screen might slow things down a bit but simplex and perlin are fairly fast duje to there simple nature. What you can do is setting up somekind of tile system for these stars, say a 10px by 10px tile system. Then run the noise on those tiles. and place your stars on those tiles. instead of having to check a 1920x1080 field (>2.000.000 spots) you reduced it to 192x108 (a bit over 20.000).

\$\endgroup\$
  • \$\begingroup\$ Thank you. I found a java implementation for perlin noise but I couldn't figure out how this helps me. I mean, I need a technique to avoid storing all generated stars in a big list. My approach is to delete them, an when I return to create new ones, but they aren't the same \$\endgroup\$ – Kronos Jul 26 '15 at 9:50
  • \$\begingroup\$ @Kronos Edited my answer. \$\endgroup\$ – Madmenyo Jul 26 '15 at 10:07
  • \$\begingroup\$ @Kronos Anyway, do you need to interact with the stars? Otherwise you can just use tileable images. If you have enough of these, a couple of times the screen size the player really won't notice the pattern. Repeating textures are used everywhere and there are several techniques to cover things up too. Off course if the player needs to interact with the stars and there randomness is part of the game this will not work. \$\endgroup\$ – Madmenyo Jul 26 '15 at 10:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.