Hi guys,
Today, I’ve been working on implementing directional movement using the Active Object system inspired by MMF2/Clickfusion 2.5. One of the key aspects I’m focusing on is how directions work, particularly when it comes to character movement and animations..
The Importance of Directions
For example, let’s say we have a character that can move in 32 directions, each corresponding to a specific angle:
0: 0, # Right
8: 90, # Up
16: 180, # Left
24: -90, # Down
4: 45, # Diagonal right-up
...(etc)
MMF2 sprite editor with directions (I’ve added the numbers in paint)
These numbers represent the character’s movement direction, but I also use them to determine which sprite animation to display.
Here’s where things can get interesting—sometimes, the movement direction and sprite direction don’t always align, depending on the game mechanics.
Independent Movement and Aiming
In top-down shooters, for example, you often want the character to look at the mouse cursor while moving in a different direction. In this case:
- The character aims at the mouse, so your shots go where you intend.
- The character uses a “look at” function to rotate toward the mouse for proper aiming.
Even though the movement and aiming directions are independent, the mechanics create fluid gameplay that feels responsive.
Synchronized Movement and Direction
On the other hand, in games like Triumph War, you need the character to move and face in the same direction.
If you press the right arrow key, the character walks to the right and also faces that way, and if you press the shooting button - it shoots at the same way, same as old arcade games.
Now last time, I said that the enemies, and “AI” in the game, is actually just a bouncing ball with some if conditions - so now I want to implement this idea, and also to do that, I needed to create some scripts to handle this direction calculation.
So, now - I can take a vector2D, Vector2(1, 0), for example this will be the right direction, and put it in a function: get_closest_number_from_angle(rad_to_deg(velocity.angle()))
and get the number of the angle,
for readability:
We take the velocity vector2D, and get the angle from it, it will be returned in radians, so we need to change it for degrees.
velocity.angle()
We get the angle.
rad_to_deg()
This will let us get it in degrees
So we get:
var angle_in_degrees: float = rad_to_deg(velocity.angle())
We put this in our function:
var result = get_closest_number_from_angle(angle_in_degrees)
Now notice how the function is called get_closest_number_from_angle
, the reason for this naming is, that you can enter any angle you want, and you will get in return, the closest angle in 32 directions in a number from the complete direction dictionary from above:
0: 0, # Right
8: 90, # Up
16: 180, # Left
24: -90, # Down
4: 45, # Diagonal right-up
...(etc)
Let’s conclude this:
We have a bouncing ball that just hit the wall, now because is a bouncing ball, its going to bounce!, so its bouncing to the opposite direction
let’s say its: -147.042197584245
Scary number, but worry not we will just put it into our functions and we will get the closest angle -146.25
:
In our dictionary this is 19.
19: -146.25,# Almost diagonal left-down
So we get 19, great!, now what?
Now we set this to the animation, as the movement is already calculated, we know now the ball (the character) is going to move to this angle -147.042197584245
Now we got 19, so we set all the animations we have, the dying animation, the walking animation, the stopping animation, etc… to the direction 19!
So for example if the number we got was 4, we could set it to this animation direction 4 here, so the character will look at this direction.
What’s Next?
OK that’s amazing, tho, really there are tons of things to do!
You might noticed a little problem yet to be solved, if we got the number 19, this is the direction of a character in Triumph war 2142 (so this are the directions of the animation of the character!):
var direction_to_number := {
"right": 0,
"diagonal_right_up": 4,
"up": 8,
"diagonal_left_up": 12,
"left": 16,
"diagonal_left_down": 20,
"down": 24,
"diagonal_right_down": 28
}
If you are super shape you might notice 19 is not to be found here, so what can we do with this number?
Well we need to create a simple function to handle this, something that will take this 19 and turn it to - 20 for example
But!, how do you know what to do with the number 22? I mean its really close to “down”, 24, but also really close to “diagonal_left_down” that will be 20!
So 20? 24? what should I do?
Should we pick at random?
Should we maybe make the character to only be able to move at 8 directions so this will be easier for us?
How it works in MMF2? (In Triumph war)
I have no idea right now, but I am working on this!
Stay tuned! 🙂