So this past week I spent some time trying to make the game look more appealing. Though I am dealing with very simple visuals I'd ideally like to come up with an art style, as I move along, that suites the simplicity of what is presented making the simple visuals aesthetically appealing.
So as you can see the hills are starting to look a little more like hills, the mountains are a little more obvious by their color and style and there is now sand/beach near the water. Of course still missing from this world is vegetation and wildlife, this will be one of the last elements I add simply because it will be very easy but time consuming do to it being artistic in scope.
Now a bit about the coding logic I developed.
Now it THREE.js there are 4 classes to make a visual element within the canvas element. I'm sure many of you are already familiar with these as they are probably universal across many languages.
THREE.Vector3() contains the x,y,z position of a vector is 3D space.
THREE.Face3() is comprised of 3 vectors,
THREE.Geometry() faces are then drawn and visual on the, counter-clockwise vector order, plane of each face. The geometry class contains a vector and face array.
THREE.Mesh() is comprised of a single geometry and a material class(). It is the Mesh that you see visible. The mesh can then be scaled and rotated and such but it's basic parts remain intact.
I'll do my best to try and describe what I've done.
to each of the vector and face classes I've assigned a unique id, just 0 to how many ever vectors/faces there are.
the three most important additions are the l array, s array and cv array. The names of which are kind of arbitrary, I just like short and simple variable names. "L" stands for "draw order" for drawing each face, "S" stands for the "unique id" for each connecting face. "CV" stands for "draw order vector id's".
the most important part is the addition of "L". Because what you don't see in my diagram 'forgot' is that the actual index position of connecting face s and cv arrays correspond to one another. That means if face id:1 has the information about face id:2 in it's 0 index position, so will face id:2 have it's information about face id:1 in index position 0. Then the draw order is preserved via the addition of "L".
A sample of the draw order looks like[code=js:1]var f = g.faces;// to draw a sample facevar F = new THREE.Face3( f.cv[f.l].a , f.cv[f.l].a , f.cv[f.l].a );// in this example F and f are identical but when ever f.s or f.cv is called up// it always contains the f.l array for reference.
Now to generate a world each of the twenty faces of the original icosahedron, with their respective encoded information about it's surrounding faces, is subdivided into nine pieces twice, then 4 pieces three to four times. The images in this post are three divisions into 4 pieces. While it subdivides the information about each new face and it's surroundings is updated and inherited, like the the case of "S" and "L" respectively. This reduces the number of "if" statements for the initial geometry that is created "a big ball", theoretically I think I could eliminate all 'if' statements, and with my system I can create this big ball of many 100,000's of faces in less than 2 seconds. Then built off of this basic geometry it is very easy to manipulate the ball and contort it as I see fit because so much information is embedded in it. This comes in handy, actually is critical, to being able to display thousands of moving objects across any path along the world later on. But I'll talk more about that once I'm done with the AI generation.
Oh one last note, current world generation time with everything included on the last build is 7.5 seconds.
Anyways, thanks for taking the time to read if you did.
Also, I'd love to hear any advice or comments about the look, the art style is my Achilles heal and I'm worried about it.
Thanks and Merry Christmas,