hey there !
So I want to display an 8 direction sprite AI character.

So far, for FOUR directions, i did this "check previous frame" > compare position> define the angle.

Looks like this :

``````var motion = position - _position_last_frame
if motion.length() > 0.0001:
#NSWE formula
_cardinal_direction = int(4.0 * (motion.rotated(PI / 4.0).angle() + PI) / TAU)

# And now you have it!
# You can even use it with an array since it's like an index
match _cardinal_direction:
0:
\$AnimatedSprite.play("W")
1:
\$AnimatedSprite.play("N")
2:
\$AnimatedSprite.play("E")
3:
\$AnimatedSprite.play("S")
# Remember our current position for next frame
_position_last_frame = position
``````

So yeah this one works.
Assuming I want 8 directions i would go for this :

``````var motion = position - _position_last_frame
if motion.length() > 0.0001:
#NSWE formula
_cardinal_direction = int(8.0 * (motion.rotated(PI / 8.0).angle() + PI) / TAU)

# And now you have it!
# You can even use it with an array since it's like an index
match _cardinal_direction:
0:
\$AnimatedSprite.play("N")
1:
\$AnimatedSprite.play("NW")
2:
\$AnimatedSprite.play("W")
3:
\$AnimatedSprite.play("NE") # SOUTH
4:
\$AnimatedSprite.play("E")
5:
\$AnimatedSprite.play("SE")
6:
\$AnimatedSprite.play("S")
7:
\$AnimatedSprite.play("SW")
``````

This one.... is giving me inconsistency. I must be doing something wrong.

2 questions...
1) Do you see a fix ? cause im getting clue less. Also I have no idea how to know which number matcher what direction... doing it manually...

2) Is there an other way you'd think of ?

Again, this is for AI, so i don't have any "input" to match.
Thanks !

in Engine

+1 vote

Numbers should be clockwise (angles usually are counter-clockwise but Godot 2D has Y axis flipped). This formula should start from West = 0 (not North). This approach is from this comment, where an example project with 8 directions is also attached to show which numbers are returned: https://github.com/godotengine/godot-proposals/issues/566#issuecomment-596266660

1) Do you see a fix ? cause im getting clue less. Also I have no idea how to know which number matcher what direction... doing it manually...

I wonder what kind of problem you are facing. What do you mean by "inconsistencies"? Did you print the numbers and the motion vector? Those basically behave like an enumeration going from 0 to 7. The example project uses an array to match them with names.

Your `match` statement also looks off. Numbers start from West, but you made it start from North. Then you go to North-West (anti-clockwise then, which is wrong way), then West, then... North-East? You changed direction^^

Proper order should be:

``````const _cardinal_direction_to_name = [
"W",   # 0
"NW",  # 1
"N",   # 2
"NE",  # 3
"E",   # 4
"SE",  # 5
"S",   # 6
"SW"   # 7
]
``````

So you can also do:

``````\$AnimatedSprite.play(_cardinal_direction_to_name[_cardinal_direction])
``````

2) Is there an other way you'd think of ?

There probably is a way which is to check every single combination of X and Y coordinates but it's incredibly tedious. I never attempted that.

by (29,088 points)
edited by