2D Skeleton

2D Skeleton

What are skeletons?

In game programming, sekeletons are part of an animation technique that is used in both 3D and 2D space. However, here we only deal with 2D skeletons. Nevertheless it remains basically the same logic.

When you create a "normal" animation, you usually take an image file with several frames, which you then display alternately with a time delay. This is a very traditional way to animate things and is still the most common form today.

However, the whole thing is very static, it's supposed to be great too. You don't have much influence on the animation and you can hardly change single frames at runtime. Imagine you have a hundred different swords in your game and you have to create the same animations for each one. A terrible effort.

Recycling

An animation that you realize with skeletons can be used over and over again. So you would have to create the sword swing animation only once and could use it for every sword. Useful, or?

Bones, Joints, ...

The term "skeleton" comes, as you might imagine, from the English and means: skeleton. This is exactly how you should imagine movements when realizing animations with skeletons.

A skeleton arm that performs a sword swing.

The animation above consists of three sprites: Upper arm, lower arm and hand. These sprites are "held together" by code. And this is exactly where the development of a skeleton begins, namely with the positioning.

We recommend that you first set the origin points of the sprites, i.e. the point around which the sprites should later rotate.

The origin is (5,5) relative to the upper arm.

For example, to connect the forearm to the upper arm now, we simply have to take the position of the upper arm and a point where we want to connect both.

Now only the position, preferably in each frame, has to be set. So the forearm is repositioned with every movement of the upper arm and it looks as if both sprites were one.

so far so simple

Movements are now covered. The sprites are connected and remain so. Only if you now try to rotate the upper arm, the forearm will not behave as you hope. Why?

This is not what it should look like.

The rotation only rotates the graphic, but the position remains the same. Thus the forearm remains untouched at its position. How do we position the forearm correctly?

We must use a rotation matrix. Without going too far into mathematics now, the 2D rotation matrix looks like this:

Please don't be scared. It's not that complicated!

Without going into detail and asking the questions "Why? Why? Why?", I only explain here (similar to math lessons in school) how to use the whole thing. x' and y' are the coordinates we are looking for and need to position our forearm correctly after rotation. To get this we have to "calculate" the 2x2 x 2x1 matrix. This works as follows:

(2x2)x(2x1) Calculate matrix.

Where's the code???

Vielleicht auch interessant
Bazooka - in Mausrichtung schießen
Bazooka - in Mausrichtung schießen

Wie man Spielelemente in Mausrichtung ausrichtet und bewegt.

You might think that everything looks more complicated than it is at first sight. That's why we're going to practice now. In code it might look more understandable.

int nx = cos(a) * x - sin(a) * y;
int ny = sin(a) * x + cos(a) * y;

Now we have to define the unknown variables x, y and a. The following applies here: Most cosine and sine functions work with RAD (0-1) and not DEG (0°-360°)! Therefore we have to convert the angle.

float pi = 3.14159265359;
float a = arm.getRotation() * pi / 180;

The positions are given relative to the upper arm! That means, if the upper arm has the position (100, 100) in the game world and the connection point we want to have is at the coordinate (126, 105), the relative point to the upper arm is: (26, 5).

.
float x = 26;
float y = 5;

Now we take the calculated position of the connection point (after rotation) and add it to the current arm position. Code says more than thousand words:

float pi = 3.14159265359f;
float a = arm.getRotation() * pi / 180.f

float x = 26;
float y = 5;

x -= arm.getOrigin().x;
y -= arm.getOrigin().y;

float nx = cos(a) * x - sin(a) * y;
float ny = sin(a) * x + cos(a) * y;
			
underarm.setPosition(arm.getPosition().x + nx, arm.getPosition().y + ny);

Tadaaa!

The whole thing can now be done for the hand and you would have a connected skeleton arm of three sprites. Of course, you can now make your life easier and use the new knowledge to create a skeleton animation class. Most frameworks offer functions for calculating matrices, so you don't have to calculate the rotation matrix manually. But it never hurts to know how it works roughly!

Leave a like or comment (~‾▿‾)~
Name Text
Kommentare

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in /var/www/html/devindie/_framework/controller/Read.class.php on line 723