UPDATE: Procedural object creation.
Ok, not really a tutorial, more of a walk-through of the process I’m experimenting with to create procedurally generated content - in this case, everyone’s favorite retro adversary, Asteroids!
I’ll be updating throughout the day as I’m working on this, so feel free to leave comments and suggestions.
I started by writing down on paper the general idea of what I wanted to do. The basic steps I’m going to follow are;
- Start with a seed number (long) that will be the random number generator seed.
- Around my center point (0,0), start creating new radial co-ordinate points every 11.25 degrees with Random(seed+loop#) radie.
- this gives me 32 points. Next create beziaer curves using 4 points at a time, going around.
- For each curve, get 20 points along its edge and add them to my asteroids Polygon
Next I threw a few sketchy classes together and ran a few renders to see what the results were;
-
Giant Space Hippy Daises of DOOM! ;D (I forgot to add the width on one of the endpoints, making it 0. Damn typos.)
http://sphotos.ak.fbcdn.net/hphotos-ak-ash2/hs017.ash2/34235_411839461716_555931716_5151115_1783637_n.jpg
- I fixed the width thing, now they’re looking a bit more like rocks. (or marshmallows)
http://sphotos.ak.fbcdn.net/hphotos-ak-ash2/hs017.ash2/34235_411839466716_555931716_5151116_1409856_n.jpg
- I wanted a bit more variance in the shape and size, so next i used the my random numbers to pick the minimum and maximum radius of each point. (before they were 100 and 500). I forgot to get a screen cap of that, but there was not a huge difference.
What I have changed here is instead of using consecutive seeds (1,2,3,4,etc) I’m using multiples of 1000. So going right to left, we see the first 10,000 generations of asteroid.
http://sphotos.ak.fbcdn.net/hphotos-ak-snc4/hs017.snc4/34235_411839471716_555931716_5151117_6794960_n.jpg
Ok, more like it. Note that the first one is still very similar to the original 10. This is because they seem to gradually evolve over time. I’ll see if i can get a video of it later.
Actually, they are a little too jagged, so I’m going to experiment a little more.
Will update when I have something.
UPDATE 2:
Whell that was easier to do that I expected…
As you can see, its a bit ropey, and for some reason, goes WAYYYY smaller than the 100px minimum size. (radii are set to be between 100-1000px … hmm)
Also, does anyone know if its possible to embed youtube vids?
Update 3:
After some tinkering and a break to let my poor aged GPU have a nap on a few occasions I got this code producing nice looking asteroid shapes;
public static Asteroid MakeAsteroid(long seed)
{
Asteroid asteroid = new Asteroid();
Vector2f[] line = new Vector2f[32];
float minWidth = 100;//RandomDice.SEED_ROLL_BETWEEN(100, 200, seed);
float maxWidth = 200;//RandomDice.SEED_ROLL_BETWEEN(minWidth, minWidth*2, seed+1);
float width;
float theta = (float)Math.toRadians(40d);
width = RandomDice.SEED_ROLL_BETWEEN(minWidth, maxWidth, seed);
Vector2f[] points = new Vector2f[9];
for(int i = 0; i < 9; i++)
{
width = RandomDice.SEED_ROLL_BETWEEN(minWidth, maxWidth, seed+i);
points[i] = Vector2f.fromAngle(i*theta, width);
}
Path path = new Path(points[0].getX(), points[0].getY());
path.curveTo(
points[2].getX(), points[2].getY(),
points[1].getX(), points[1].getY(),
points[1].getX(), points[1].getY(),
4);
path.curveTo(
points[4].getX(), points[4].getY(),
points[3].getX(), points[3].getY(),
points[3].getX(), points[3].getY(),
4);
path.curveTo(
points[6].getX(), points[6].getY(),
points[5].getX(), points[5].getY(),
points[5].getX(), points[5].getY(),
4);
path.curveTo(
points[8].getX(), points[8].getY(),
points[7].getX(), points[7].getY(),
points[7].getX(), points[7].getY(),
4);
asteroid.outline = path;
return asteroid;
}
I recorded a quick vid showing the variety of sizes that come out of the generator (again, incrementing the seed by 1000 for each asteroid.)
One think I’ve noticed right off the bat is that rendering primitives like this seems a lot more intensive* than rendering images. In previous tests with image asteroids i can have 10,000+ all moving around no problem but with these, things start chugging at about 300.
*By ‘intensive’ I mean my GPU keeps crashing, which literally shorts out my PC causing a hard shutdown. I’m open to the idea that this may be more of a hardware problem than anything I’m doing… I think that I might be one of the few people who still owns a GeForce MX440. (some retro right there for ya)
I’m going to look into ways of getting the performance up to scratch. Firstly, the only time there’s ever going to be a load of these things rendering is when the camera is zoomed way out, so I’m going to modify the factory method to provide 4 different shapes to render, ranging from a 100+ point high-detail path to a single point dot, depending on the camera zoom.
Next I’m going to get an asteroid-field builder factory type thing so that I can split up the playing field into sections that I can dynamically load (from local cache or server) on the fly as the player moves in and out of range. (one game play dynamic I’ve been thinking of to hide this is a player can only see what his ship’s sensors can see - so the same way that we know that there’s moons around Saturn, we only know what they look like when we have a probe up close.)
My TODO List Next:
- I cant remember what its called but that level of detail thingy.
- Procedurally generate a 1000*1000km asteroid field.
- Make a level reader to load these on the fly from an XML file.
Update 4:
I put a LOD variance on, but have not integrated it properly yet.
I got fed up with coding, and hit Photo shop to make myself some maps. Below is the asteroid density for (sorta) our solar system.
If you’re nerdy and you know it; Ring in the center is the Main Belt, the three blobs around that are the Trojan, Greek and Hildas(sp?) fields (in Jupiter Lagrange points). Out beyond that is the main mass of Kupiter belt objects and beyond that is the little knows Artistic Licence belt.
http://sphotos.ak.fbcdn.net/hphotos-ak-ash2/hs102.ash2/38433_411970351716_555931716_5154243_5907069_n.jpg
The idea is that I can use this to generate the asteroid density procedurally in a game world that actually is 80AU from Sun to edge - LOADS of scope for MMORPGR action!
Going to call it a day now and get back to it in the morning, hopefully with the zone-loading map rather than trying to do it all at once. (even a 50*50 pixel (on the map image) ended up with 40K asteroids, lol).
Have a good evening if you’ve been following along,
Matt