The first thing I wanted to do was put some stars in the spacious sky. I could have hand distributed them in a graphics program created a pattern and let them hang out, but I wanted to have the stars move a little when the user moved the mouse, so that it looked like you were actually moving in space. To do that I’d need some close stars that moved a little, a middle section that moved a little more and a backward section that moved a lot (this may be the wrong order of movement, but as you’ll see, I didn’t get it working anyway). I could have still done this manually, but getting them to look distributed, but random-ish is difficult to do by hand (I always feel like I’m accidentally making a pattern) So I went looking for an algorithm to do that for me. Turns out a good algorithm for this is the Poisson Disk Sampling algorithm. I got that working in vanilla JavaScript (more on that later). And thus I had my star fields. Let’s make them move!
You may have noticed if you’ve looked at the site that in the final version the stars don’t move in relation to the mouse, well this was the first of many ideas that didn’t pan out. I spent like a week trying to make it work. The movement always felt wrong and eventually I just gave up.
On to the lasers! My initial vision was that these would shoot out from the left and right about halfway down the screen. They’d then meet in the middle and destroy anything in their path. I also wanted it to look like they were shooting into space using perspective. How hard could it be?
So, so much harder than I thought.
I spent so long on the lasers and getting them to even partially look right that I nearly gave up on the space battle design entirely. I was able to get lasers to fire and if I was shooting in the middle of the screen everything looked great, they’d cross and keep going, but they were getting there at the same time. If I shot anywhere besides the center they would arrive at different times. I tried a whole bunch of things, I tried setting a ratio, I tried having a “double cannon” that I moved to the bottom and shot two lasers out of at once. This worked, but looked wonky because the two beams had to have a fixed perspective that didn’t match actual perspective once it got past the initial shot. I tried weird complex math that wasn’t so much about high level math as it was me trying to throw mathematical things at the problem till I solved it.
At one point, I got it so that a large swath of the screen (maybe 60%) acted the way I wanted, but the rest of the screen would not bend to my will for all the math in an engineering degree. (While most Computer Science degrees are in an engineering school, mine wasn’t, at least not till after I graduated, which may tell you all you need to know about my math abilities). Finally, after far longer than it should have taken me, I realized that there was a branch of mathematics that actually could solve this problem, even in 3d space, trigonometry! Hey junior year of high school, I’m looking at you!
I thus set to work on implementing “the trigonometry” to achieve my goals. I got it working in two dimensions pretty easily, but the third dimension was tough. I banged my head against this for a long time until finally I got it! The cannons were placed about halfway down the screen and their beams shot at whatever point I clicked, meeting at the same point at the same time and disappearing.
It worked at the horizontal middle and as far as I wanted to go to each side. And then I clicked at the vertical middle where the cannons were directly across from each other. While the beams still met in the middle, there was a problem. See I was using css transforms to add perspective and they were working great except that at that vertical midpoint, the elements I was using for my cannon and the lasers were almost exactly side on meaning they virtually disappeared (kind of like looking dead on at a piece of paper’s thinnest side).
To make matters worse if I fired below the vertical middle, it fired backwards at the viewer. An epic space battle, this would not be.
I tried a bunch of things again, attempting to turn the cannons and laser beams so that they were always showing their top side, but my attempts at this still left inconsistent results and added different places where the cannons and beams were still thin side up. Plus it ruined some of the perspective look I was working on. Finally I decided to move the cannons to the bottom so that the space where things got wonky was limited to the bottom of the page instead of the very middle. This helped, but still wasn’t everything I wanted.
Then I came up with the idea of 3d-ish cannons. So instead of having one element that turns and spins with a thin side that makes it go almost invisible, I took that element and created a duplicate (using a pseudo element) and turned it 90 degrees in the z direction/down the length of the barrel. When looking from the back of the cannon it looks like a cross, but without any shading (a blessing in this case) it blends in with the original so that the cannon looks thicker at more angles than just the flat shape does.
This helped a lot, but still lead to the barrel getting too thin at times, you see when you turn a plus sign 45 degrees it’s a decent amount thinner than it is at full height. I then added a second copy (a second pseudo element). I turned one copy 30 degrees and the other copy 60 degrees. This still allowed for a slightly thinner barrel at certain angles, but was not super noticeable and, without doing a thousand copies turned at small intermediary angles would be about the best compromise between visual looks and performance (plus with just two, I could use the before and after pseudo-elements and not have to worry about stuffing other elements in there)

