0 votes

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

in Engine by (170 points)

1 Answer

+1 vote
Best answer

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]
by (1,605 points)
selected by

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!

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

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.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.