I have made a weapon in Evil Robots that casts lightnings to nearby enemies.
In this post I wanted to show you how I approached it.
I made a demo that you can find in github.
Eventhough my game uses OpenGL, for this demo I have used the sokol library. I chose to use this library because it’s a very simple and easy to use library, and it can be compiled to most platforms (including web). Besides I wanted an excuse to give it a try out and learn something new :).
Generate a tree
The first step is to create a tree such at this one:
I got the idea from this StackOverflow answer
The idea of this technique is to start with a line that joins the origin and destination points. That line is split more or less at the middle, and then we apply a random offset to it perpendicular to the direction of the line.
Do that recursively and you will get a jagged line.
We would like to also add ramifications to the lightnings. Each time we make a split, we might also add a ramification with some probability.
We store each “joint” or node in a linear array as a position. Then we have another array of indices, which connects the nodes as a tree data structure. Along with the position, you can also store a power or energy. The energy at the root node is maximum. Each time there is a ramification, the power is split such that sum of powers is preserved. We will use this power later to give proportional thickness to the lines.
Generate a triangle mesh
The last step consist of giving these lines some thickness.
This part turned out to be the most difficult. Eventhough the core idea is quite simple, I found lots of problems in the corner cases. I managed to handle most of those special cases, but still, the results are not always 100% satifying with very thick lines.
The basic idea is to cast parallel lines according to the thickness of the segment, and compute the intersection points.
After that it’s just a matter of joining the points to form the triangles.
The tricky part it handling the corner cases. What happens when two lines are parallel (or almost)? The intersections points go to infinity or nans. I tried to handle those but I think it’s not perfect. Here’s the relevant code.
Onother detail to take into account is orienting the triangles towards the camera, in order to achive a billboarding effect.
>> Home