Chage enemy directional animation that an enemy who follows player

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

So, I’m making a kind of 2D top-down game with a fake sense of 3D profundity, similar to the old games, and all the movable sprites have four animated sprites: one for front, one for back, one for right and one for left.

It was easy to link the animation between player and keyboard Inputs, just put the Input pressed with correct animation direction.

But all my enemies are following the player with variations of this line on the script:

func _physics_process(delta):
if enemy_1_FOV == true:
	var vec_to_player = player.global_position - global_position
	vec_to_player = vec_to_player.normalized()
	move_and_collide(vec_to_player * RAND_SPEED * delta)

How can I could change the animations of enemies with this?

TKS guys

:bust_in_silhouette: Reply From: Eric Ellingson

If your vec_to_player will only ever be (1, 0), (0, 1), (-1, 0), 0, -1), then you can use a map like:

const FACING = {
	Vector2(1, 0): 'right',
	Vector2(-1, 0): 'left',
	Vector2(0, 1): 'down',
	Vector2(0, -1): 'up',
}

and then:

func _physics_process(delta):
    if enemy_1_FOV == true:
        var vec_to_player = player.global_position - global_position
        vec_to_player = vec_to_player.normalized()
        move_and_collide(vec_to_player * RAND_SPEED * delta)

        var anim_direction = FACING[vec_to_player]

Hi Eric;

I was kind a busy and I have not seen your answer.

I the mid of time, I made with my noob way something like that:

func _process(delta):
if player.position.y >= position.y:
	get_node("enemy_1_sprite").play("walking_front")
if player.position.y <= position.y:
	get_node("enemy_1_sprite").play("walking_back")
if Input.is_action_pressed('left') and enemy_1_FOV == true:
	if player.position.x <= position.x:
		get_node("enemy_1_sprite").play("walking_left")
	if player.position.x >= position.x:
		get_node("enemy_1_sprite").play("walking_right")
if Input.is_action_pressed('right') and enemy_1_FOV == true:
	if player.position.x <= position.x:
		get_node("enemy_1_sprite").play("walking_left")
	if player.position.x >= position.x:
		get_node("enemy_1_sprite").play("walking_right")

Changing the Y animation (front and back) with a relative position of player and changing the X animation (right and left) with a confirmation of position + Input + FOV.

It’s huge and a lot of “if” but iit’s working as I expected (testing video)

But I will test with your way. It’s much more elegant and simple.

Thanks!

lucasfazzi | 2019-02-19 22:25

Ok. It looks like it probably won’t work exactly like how I posted. But I think it could be changed to work.

This should give you what you want:

const FACING = {
    Vector2(1, 0): 'right',
    Vector2(-1, 0): 'left',
    Vector2(0, -1): 'down',
    Vector2(0, 1): 'up',
}

func get_facing_vector(vec_to_player):
	var min_angle = 360
	var facing = Vector2()
	for vec in FACING.keys():
		var ang = abs(vec_to_player.angle_to(vec))
		if ang < min_angle:
			min_angle = ang
			facing = vec
	return facing

func get_facing_direction(vec_to_player):
	var facing_vec = get_facing_vector(vec_to_player)
	return FACING[facing_vec]

So since vec_to_player won’t actually almost ever be exactly (1, 0), (0, 1), (-1, 0), 0, -1), we want to loop through those for vectors and see which one is closest to vec_to_player, and use that one.

So now you can call get_facing_direction() to get ‘left’, ‘right’, ‘up’, or ‘down’.

Eric Ellingson | 2019-02-20 04:39