A.I, Data and Software Engineering

Smooth nature snake – game redev with Kotlin (part 3)

S

In part 2, I introduced how to make the serpentine movement. We continue this article by covering the turning mechanism for the snake.

Challenges in turning animation

As we want our snake looks as smooth as possible, the two challenges are:

• Firstly, the head should slowly change to the target direction rather than a sudden turn. As the head has a distinct shape, we need to make sure the accuracy of its heading direction. Figure 2 illustrates an easier case when the snake does not have a head.
• Secondly, its body should form a curved line when making a turn. We don’t want to see the snake breaks its neck/body with an immediate 90-degree turn as shown in many classic snake games (Fig 2).

Now, we will step by step address these two problems.

The principle is simple:

• Calculate the turning angle
• Divide the angle into serval equal arcs, the smaller arc, the smoother the transition
• Draw the head based on the arc

As we created a function to calculate the new position when rotating axes, the implementation of this is straightforward. Nevertheless, you can also approximate arc changing by the different of two movement vectors, i.e. currentMoveVector and TargetMoveVector.

If you use the approximate method, you may also need to compare two vectors to check if the head’s direction reaches the targeted direction. For this, I used the cosine similarity. If the value is -1, the two vectors have absolute opposite directions. If the value is 1, they follow an identical direction (Fig 4).

$$\cos(\theta) = {\mathbf{A} \cdot \mathbf{B} \over |\mathbf{A}| |\mathbf{B}|}$$

And the code for the cosine similarity:

The snake will stop turning if the cosine similarity reaches a certain threshold. I used 0.98 in this case.

Make curved line turn

It is almost there. If you have completed the turning and the movement of the head. The curved line will magically appear. The explanation is simple as it is the result of vector addition:

• The snake’s head currently has two movements simultaneously, namely, the movement vector (mCurrentMoveVector) and the turning vector created from the arc.
• When adding up the 2 vectors, we have a new vector representing both the movement and turning direction.
• Fig 5 demonstrates the turning step of a snake. If the snake wants to turn slowly from $$\vec{A}$$ to $$\vec{R}$$. It can change the direction by adding $$\vec{B}$$, $$\vec{C}$$ , $$\vec{D}$$ , $$\vec{E}$$

$$\vec{R}=\vec{A}+\vec{B}+\vec{C}+\vec{D}+\vec{E}$$

$$\vec{OE} = \vec{OA}+\vec{AB}+\vec{BC}+\vec{CD}+\vec{DE}$$

The final step is to implement the the head turn animation in a separate thread. We can use Runnable interface as follow.

The result

Let see our joyful snake wandering around the game view.

Source code: Github (continue update).

A.I, Data and Software Engineering

PetaMinds focuses on developing the coolest topics in data science, A.I, and programming, and make them so digestible for everyone to learn and create amazing applications in a short time.