0 votes

hey there !
So I want to display an 8 direction sprite AI character.
My character follow a getsimplepath.

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 !

asked May 18 in Engine by quizzcode (152 points)

1 Answer

+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.

answered May 18 by Zylann (26,153 points)
edited May 18 by Zylann

Thank you for your reply.

Your solution is much cleaner and your link helped me understanding the process.

thanks !

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.