Inverse Kinematics In Game Maker
Inverse kinematics is calculating the position of limbs and angle of joints in a system in order to make them reach a desired end position. In other words when considering a point calculate what angle limbs should be in to touch it. This is useful in games when making arms bend to hold objects, making legs touch the ground on uneven terrain or even rendering simple ropes.
Almost a year ago I worked on a fairly large student project with three other members. The project was to build a game using Game Maker Studio 1.4. and during this project one of the things that I ended up needing was a simple inverse kinematics script. Unfortunately I was not able to find one. This is to provide the script that I ended up using as well as an explanation as to how it works for any one interested. If you are interested in the project that I needed this for, it was a adventure/rogue lite game. It is playable on Windows or Linux and you can check it out here at Artificial.
In 2D, inverse kinematics can be achieved using fairly simple trigonometry so don’t expect to learn any fancy new mathematical techniques. However I do hope that this script may be useful for anyone who needs it.
If you are only interested in the full script you can find it directly below. Further down is my explanation if you are interested in learning about how it works. This code is provided as is and under the MIT licence.
Code
Arguments:
- orig_x, orig_y (number): The coordinates of the first connected point
- target_x, target_y (number): The coordinates of the second connected point
- length1 (number): The length of the first section
- length2 (number): The length of the second section
- flip (boolean): Flip will inverse the angles. Making the joint bend in the opposite direction
- sprite1 (sprite_index): The index of the sprite to draw over section #1
- sprite2 (sprite_index): The index of the sprite to draw over section #2
Full Script:
|
Explanation
Skipping the argument to variable conversions the first lines of code that we run into are:
|
This simple calculates the distance of the origin to the target as well as the angle between them. A 2D inverse kinematic system is essentially a triangle where three lengths are known. The length of both arms and the distance between the origin and target make up the full triangle. The base angle is needed because our final result will need to reflect the original orientation of the points.
Now we can begin by calculating one of the interior angles. Specifically starting with the angle from the origin to the joint between both arms. Or the angle of the first sprite.
|
Note that we clamp the cos_a value between -1 and 1. That is because arccos is limited to that domain and is not continuous over all real numbers. In practice doing this locks the ams to a max and min angle rather than having them break if the target is too far away for the system to reach.
That code was an implementation of the law of cosines where Θ is the angle from the origin to the joint between both arms.
Law Of Cosines:
|
This next stage is purely for show. Flipping the angle allows the system to mirror real bones and not bend at angles that would be unrealistic.
|
Now we can move on to using the angle that we calculated. Remember that our triangle is not oriented in any meaningful world space form. To calculate the actual angle in world space the code simply adds it to the base angle. Here it is also converted back to degrees since GML uses degrees.
|
Next we can calculate the point where the new joint is by simply adding the vector representing our first arm to the origin point. This results in the point where both arms meet.
|
Finally we can use the joint position and the target position to calculate the final angle. Since both of these are worldspace points there is no need to add the base angle.
|
Now we have all three points on the triangle and the angles between them. The final stage is to draw the sprites and they will be positioned properly.
|