Gather the "facing direction" of a node to display 8 direction sprite

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By quizzcode

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

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 !

:bust_in_silhouette: Reply From: Zylann

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: Add diagonal constants to Vector2() like UP_LEFT · Issue #566 · godotengine/godot-proposals · GitHub

  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])
  1. 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.

Thank you for your reply.

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

thanks !

quizzcode | 2020-05-18 16:21