Monday, October 25, 2010

Project 1 - Building a solar system

Now, at last, we start our first foray into the actual game elements. Part of the game is meant to be about exploration, and we need somewhere to go. For science fiction, that generally means new planets. But planets don't just exist by themselves, they orbit a star, and are orbited themselves by satellites.

What do we need to create a solar system? We need a star, first of all. Many stars actually have a companion star forming a binary system, and even larger sets exist, but for now I'll focus on single star systems.

This star is going to be orbited by all manner of bodies. Comets, asteroids, planets, gas giants, etc. We can make a list of the bodies orbiting a star. The different bodies orbiting the star, at the same time, may also have their own satellites, which we can list as well. So the bodies in a solar system can be organized as a list of lists.

Let's take for instance our own solar system. The objects would sort themselves as

|- Mercury
|- Venus
|- Earth
|   |- Moon
|- Mars
|   |- Deimos
|   |- Phobos
|- Asteroid Field
|   |- Ceres(dp)
|- Jupiter
|   |- Io
|   |- Europa
|   |- Ganymede
|   |- Callisto
|- Saturn
|   |- Mimas
|   |- Enceladus
|   |- Tethys
|   |- Dione
|   |- Rhea
|   |- Titan
|   |- Iapetus
|- Uranus
|   |- Miranda
|   |- Ariel
|   |- Umbriel
|   |- Titania
|   |- Oberon
|- Neptune
|   |- Triton
|   |- Nereid
|   |- Larissa
|- Pluto (dp)
    |- Charon
|- Eris (dp)
|   |- Dysnomia

The list isn't exhaustive. I'm focusing on those with the largest masses. There's also comets, which I didn't add, and the Kuiper Belt, but for now this list will do.

So, to start off, I need a way of storing this list. The STL gives us Vectors. But since Vector is a template, we need to determine what data type best describes the planets themselves. We can create for now a 'CelestialBody' class that will hold the information of each planet, and one vector. So our first celestial body is the sun, which will have a vector with pointers to the planets orbiting it, which will each have a vector of pointers to the moons orbiting them.

class CelestialBody
        vector<CelestialBody *> satellites_ ;



The code for setting the system up is ugly and has a lot missing, but we'll sort that out later. We want to be able to draw it before we can create new systems elegantly.

    // System Setup

    Sol.satellites_.push_back( new CelestialBody ) ; // Mercury
    Sol.satellites_.push_back( new CelestialBody ) ; // Venus
    Sol.satellites_.push_back( new CelestialBody ) ; // Earth
        Sol.satellites_[2]->satellites_.push_back( new CelestialBody ) ; // Moon
    Sol.satellites_.push_back( new CelestialBody ) ; // Mars
        Sol.satellites_[3]->satellites_.push_back( new CelestialBody ) ; // Deimos
        Sol.satellites_[3]->satellites_.push_back( new CelestialBody ) ; // Phobos
    Sol.satellites_.push_back( new CelestialBody ) ; // Asteroid Belt
        Sol.satellites_[4]->satellites_.push_back( new CelestialBody ) ; // Ceres
    Sol.satellites_.push_back( new CelestialBody ) ; // Jupiter
        Sol.satellites_[5]->satellites_.push_back( new CelestialBody ) ; // Io
        Sol.satellites_[5]->satellites_.push_back( new CelestialBody ) ; // Europa
        Sol.satellites_[5]->satellites_.push_back( new CelestialBody ) ; // Ganymede
        Sol.satellites_[5]->satellites_.push_back( new CelestialBody ) ; // Callisto
    Sol.satellites_.push_back( new CelestialBody ) ; // Saturn
        Sol.satellites_[6]->satellites_.push_back( new CelestialBody ) ; // Mimas
        Sol.satellites_[6]->satellites_.push_back( new CelestialBody ) ; // Enceladus
        Sol.satellites_[6]->satellites_.push_back( new CelestialBody ) ; // Tethys
        Sol.satellites_[6]->satellites_.push_back( new CelestialBody ) ; // Dione
        Sol.satellites_[6]->satellites_.push_back( new CelestialBody ) ; // Rhea
        Sol.satellites_[6]->satellites_.push_back( new CelestialBody ) ; // Titan
        Sol.satellites_[6]->satellites_.push_back( new CelestialBody ) ; // Iapetus
    Sol.satellites_.push_back( new CelestialBody ) ; // Uranus
        Sol.satellites_[7]->satellites_.push_back( new CelestialBody ) ; // Miranda
        Sol.satellites_[7]->satellites_.push_back( new CelestialBody ) ; // Ariel
        Sol.satellites_[7]->satellites_.push_back( new CelestialBody ) ; // Umbriel
        Sol.satellites_[7]->satellites_.push_back( new CelestialBody ) ; // Titania
        Sol.satellites_[7]->satellites_.push_back( new CelestialBody ) ; // Oberon
    Sol.satellites_.push_back( new CelestialBody ) ; // Neptune
        Sol.satellites_[8]->satellites_.push_back( new CelestialBody ) ; // Triton
        Sol.satellites_[8]->satellites_.push_back( new CelestialBody ) ; // Nereid
        Sol.satellites_[8]->satellites_.push_back( new CelestialBody ) ; // Larissa
    Sol.satellites_.push_back( new CelestialBody ) ; // Pluto
        Sol.satellites_[9]->satellites_.push_back( new CelestialBody ) ; // Charon
    Sol.satellites_.push_back( new CelestialBody ) ; // Eris
        Sol.satellites_[10]->satellites_.push_back( new CelestialBody ) ; // Dysnomia

Well, this is as far as we go for now. We have a bunch of celestial bodies created now, but as far as the computer is concerned, they're all exactly alike. The only thing distinguishing them is their position in the vector. Next up, we'll work on a way to display this.


  1. Is there anything that you've listed here that indicates the position in the vector of the planets? I'm only skimming here (not really trying to parse each line of code for instance), but it seems like you're just defining objects as far as I can tell. Is the positioning code taking place off-camera as far as the blog goes? (For reference, yes I have read the next post which describes the positioning in terms of orbital units, but that describes the values not the code that makes use of the values).

  2. The code up there is only for building the data structure that will hold the solar system. The elements in the vector aren't very descriptive about themselves.

    As you can see in the class definition for CelestialBody, all a 'CelestialBody' object contains is the constructor and destructor (which will eventually do stuff, but for now can be considered empty functions) and a vector.

    The way the solar system is constructed is by first declaring a celestial body we call Sol (I actually didn't show that line, but it would amount to the declaration:

    CelestialBody Sol;)

    Sol has a vector called satellites_ that we can access from outside the class, as it has been given public access. So whenever we write Sol.satellite_ we are referring to this vector.

    push_back(T element) is a method belonging to vector. We can access the methods in an object the same way we refer to members (assuming they are public), with the dot. So


    gives the 'something' parameter to the push_back method of the satellites_ vector in Sol.

    What push_back() does is add the element sent to it as a parameter at the end of the vector. So each time we call push_back, we are increasing the size of the vector.

    It starts empty, so the first push_back call increases it's size to one, and adds the element to position 0.

    We can refer to each element in a vector as if it were an array, with the [] operator. satellites_[0] refers to the element at position 0 in the satellites_ vector.

    Keep in mind that satellite_ and satellite[0] are different things, of different types. satellites_ is a vector, satellites_[0] is a CelestialBody pointer.

    In short, right now I'm just giving the elements a place to live, but there's no position information (other than their position in the array, which is given by the order in which they were entered and not something internal to the elements).