Good day or night. In my free time I am developing a space game on Three.js / WebGL and decided to write a small series of articles on some of the components of the game, in this article we will talk about the galaxy map. The story will go in the usual way - steps.
I will not give the initialization code and details of Three.js itself, the network is full of information about this.
And our first step ...
Step 1 - Black and Black Background
First we need to make the substrate. This is done elementary in one line:
renderer.setClearColor(0x000000);
It will look like this:
Obviously, this is Malevich's Rectangle and this is where we finish the first step.
Is it really that simple?
Step 2 - And the Sky Full of Stars
Malevich's rectangle is just wonderful, but you still have to add stars.
As we make a map of the galaxy, we need a spiral similar to the galaxy. I chose a
logarithmic spiral .
First we write down all the variables we need.
We write the algorithm, which is very simple: we go through the cycle and calculate the coordinates of each star (formula in Wikipedia) and slightly shift them randomly, so that it looks more like a galaxy.
Since the number of points is very large, we decorate them with a system of particles, the lags will be much less:
The addStar function at this stage:
var addStar = function(x, y) { var v = new THREE.Vector3(); vx = x * 10; vy = y * 10; geometry.vertices.push(v); }
And we did it ...
Something in the center of some kind of hole, let's look closer:
Disgusting, but not difficult to fix, add two cycles.
The first cycle is a generic ring of points:
for (var i = 0; i < 4000; i++) { var vec = {x:Math.sRandom(0.8, 1.7),y:0}; var angle = Math.sRandom(0, Math.PI*2.5); vec = VectorRot(vec, angle); list.push({x:vec.x, y:vec.y}); }
The second cycle generates a circle of points:
for (var i = 0; i < 4000; i++) { var vec = {x:Math.sRandom(0.001, 0.8),y:0}; var angle = Math.sRandom(0, Math.PI*2.5); vec = VectorRot(vec, angle); list.push({x:vec.x, y:vec.y}); }
Great, we already have something like a galaxy. But we need the names of our stars. You%% username has a name, but the star does not. Is it fair?
')
Step 3 - Star named% starname%
Well, let's do it consistently.
We need to make a function to generate a name. We need a global list of stars (coordinates + name). It is necessary to modify the addition of stars and include the name generation there. This is by the very presence of names. You also need a function to display the name of the star at the mouseover event. The problem is that since this system of particles just does not hang an event, it means you need to think of something else. There are many options, but I did the following: I found the JS implementation of KDTree, and drove into the tree all the points that we have (that is, the global list), and wrote the following in the mousemove event handler:
Each time the re-create the mesh is not too optimal of course, but the performance is enough.
I will not give all the code, who will be able to go at the end to the githab and look, and we will look at the pictures before the next step:
Step 4 - Putting order in chaos
So, we already have a galaxy, the names of stars, we can see them, but since we have a map, then we need a partition of space. If I say: “Rumor, fly to the TX-82 system and buy me kefir”, it will be unclear where to fly, because a) it’s not a fact that the system with the name TX-82 is the only one, b) how to find a system among over 20k stars ?
c) not the fact that kefir has already been delivered .
We make this breakdown: there are quadrants, there are sectors. The entire galaxy is divided into 4 * 4 = 16 quadrants, 4 on each side. Each quadrant, in turn, is divided into 4 sectors. Those. we can address the system as a quadrant # qX-qY - sector (sx-sy) - system% starname%.
We do this with banal lines, again I don’t give the code, it’s big and not interesting - just the calculation of the coordinates of the beginning and end of each line. Who cares - welcome to githab.
The result, as you might have guessed, is in the header of the article. But I will give another picture:
Just need to add more symbols - text, like (1-1), (3-3), (2-3). There is a grid, but no symbols. We add.
Step 5 - Chip and Dale
Let's save from misunderstanding what these numbers are in the picture above. Or at least try. Yes. Two lines of HTML and CSS:
<span id="quad" style="position:absolute;left:100px;top:10px;color:white;font-family:Arial;font-size:19px">#xy Quadrant</span> <span id="sector" style="position:absolute;left:100px;top:30px;color:#555;font-family:Arial;font-size:19px">(sx-sy) Sector</span>
Step 6 - Where am I?
And the last thing left for us is to indicate our position in the galaxy. I hit the brick on the head, I forgot where I was. But we need to tell where to bring kefir, what should we do? We open the map and thanks to technology:
Yes, the code is:
Conclusion
So we made a map. I didn’t cite many things in the article, for example, shifting the map by holding the key, zoom, I didn’t work with Three.js much, in my opinion this is a second time and not so interesting.
Github:
github.com/MagistrAVSH/galmapThe demo works in the latest FF, Chrome, Opera. In IE11, it will work badly, you will not see any labels at all, it crookedly supports WebGL.
magistravsh.imtqy.com/galmapFor the future, there are ideas to write articles about the map of the star system, about the generator of nebulae, the generators of various objects, and in general on the theme of fantastic space :) If you are interested in it - write.
Finally, under the spoiler a couple more screenshots.