📜 ⬆️ ⬇️

Game HellWorm. Development history

Good day! I would like to tell you about my experience of creating a mobile game on Unity called HellWorm. From the name you can understand that the game is about a worm. We crawl, eat coins, do not crash into obstacles. It would seem a clone of the classic game, on which most of us grew up. But, in fact, the parallel with the snake ends here.


The game also positions itself as an endless runner, in which there is a constant movement forward, without the ability to turn off the vertical route. And with all this, the worm itself can somehow wriggle (yes, yes, and even creep through itself). As a result, I would like to focus on the difficulties that I experienced trying to realize the movement of such a simple character.

Management is quite simple and is described by only one phrase:
“Wherever you click, it crawls there”.


The first implementation of the motion algorithm is clearly demonstrated in the diagram below.
')

The essence of the movement is as follows: with the speed n the length of the first segment (head) increases and the length of the last (tail) decreases with the same speed, and at the moment of pressing the screen a new segment is created. The connection goes along the central lines of the rectangles. And at the joints, to smooth the cuts, placed a circle of radius equal to the width of the segment. However, this method, unfortunately, did not fit, since the visual style of the game does not imply the use of rounded corners. I had to reinvent the wheel further, so please read the following implementation.


Docking occurs not along the central lines, but along the corners of the segments: along the left or along the right, where the side is selected depending on which side of the new point P lies on the side of the line AB

(Bx - Ax) * (Py - Ay) - (By - Ay) * (Px - Ax), if the expression> 0 then the point P lies on the left side.

How to find the coordinate of the docking point, I will not paint, because nothing special about it, simple geometry. Better to tell you more about the approach itself.

I want to immediately say that in this case the maximum angle between the segments should be no more than 90 degrees, otherwise, as you can guess, the corners will come out. Therefore, during steep (> 90 degrees) turns, a transition segment is added.


When a player clicks on the screen, the angle the worm must rotate is remembered and as soon as the head segment reaches the allowable length, a new segment is created at a given angle, provided that it is no more than 90 degrees, otherwise a transition segment is created, and when it reaches a given length, then there is a final turn. This strategy allows you to avoid chaotic distortions with a very quick touch on the screen, and also makes the movement more natural. I would like to note that there are no visual delays in the management at all.

The experiments ended and the development of the game continued: various types of obstacles were added, level generation, a store with skins, bonus coin mode when selecting a shard, changing the color of the environment depending on the distance traveled, etc. During this time, my eyes decently “zamililsya” and I just did not notice a misfire in my algorithm for the movement of the worm. Namely, small jerks when changing direction. As it turned out, the whole thing is in joining the segments at the extreme points.


When creating a new segment in this way, it is not possible to connect the centers of the sides of the segments (red and blue dots in the figure). And since the worm's head is always tied to the center point of the first segment (and the tail is tied to the center of the edge of the last one), a jerk occurs when turning, and the greater the angle of turn, the more jerk is noticeable. Of course, at the final stages of development, it is very disappointing to deal with this, because you need to redo the whole algorithm. But the desire to finish the project polished and without jambs took over. It was decided to return to the first implementation of the algorithm, since It is much simpler and more logical to calculate with respect to the broken solid line around which the body is built. It remains to solve the problem with the joints of rectangles, namely, how to fill them.


After some thought, the idea came of extending the segments towards each other to eliminate the gap.


The decision turned out to be quite working, and, surprisingly, everything worked the first time. The mathematical steps are as follows:


In general, the development of the algorithm for the movement of the worm was successfully completed. Separately, I would like to note that this algorithm can be used to create a worm or a snake with rounded (realistic) edges when bending. To do this, it is enough to set the maximum turning angle of about 10-15 degrees, and also to reduce the allowable length of the segment for the turn. The result is shown below:


In addition, I would like to tell a few words about the generation of the surrounding world. All objects are saved in sprite sheets in black and white. Frames that change colors during the game are painted over with white, because by changing the color of the Sprite Renderer all the white areas become exactly the chosen color.


(side walls with Polygon Collider 2D added, and background image)

The same technique is used for game obstacles and the main character.


In the screenshot with obstacles you can see blue and yellow diamonds, these are places where a coin can appear (yellow) or a shard (blue). They are empty gameobject with the selected icon.


I chose this approach, firstly, to simplify the task of adding coins / skulls to the scene (do not bother with random generation) and, secondly, that they appear in places that are interesting for the gameplay. And, since in the game there are about 70 different tunnels, rocks and aisles, then the player is not so noticeable predefined places.

I'll tell you a few words about the worm, namely his head. The player has the opportunity to change it (like other parts of the body), and, including, the color of the skin and eyes.


It was not obvious to me how to implement this. Therefore, the solution that appeared may not be the most competent, but working one.


There is a worm_head head prefab, in which all head + n heads are located, consisting of head objects (white sprite head) and eyes (sprite with eyes located on top of the head, which is also white). By default, all head + n objects are invisible. During the start of the game, the number of the installed head is checked to make the head + n object visible. Along with this, the color scheme chosen by the player is applied: the main color is set for the sprite of the head, body, tail, and additional colors are set for the eyes and spikes.

head.GetComponent<SpriteRenderer>().color = headColor; eyes.GetComponent<SpriteRenderer>().color = eyesColor; 

In my opinion, I told about the most interesting and not obvious moments of development, but if someone has questions, I will be glad to answer them!

Thanks for attention. You can play the game on Google Play.

PS There is no publisher for the game, we are trying to unwind on our own.

Source: https://habr.com/ru/post/318938/


All Articles