0 votes

Hello folks. I've recently started learning Godot by working on a little grid-based game. I've managed to adapt the AStar pathfinding in the provided demo for my own game's structure, and it suits my needs quite well. However, there's one aspect of the demo I can't quite figure out how to get working:

Cancelling works, at least

Relevant code:

func _process(_delta):
            if Input.is_action_just_pressed("left_click"):
                if trying_to_move:
                    movement_interrupted = true
                else:
                    trying_to_move = true
                    target_pos = get_global_mouse_position()
                    var path = get_parent().find_path(position, target_pos, debug_can_walk_on_water)
                    path.remove(0)
                    while not path.empty() and not movement_interrupted:
                        set_sprite_facing(as_direction(path[0] - position))
                        var func_var = do_move(path[0])
                        yield(func_var, "completed")
                        path.remove(0)
                    finish_move()
func do_move(target_pos : Vector2):
       if not movement_interrupted:
               $Tween.interpolate_property(self, "position", position, target_pos, seconds_per_step)
               $AnimationPlayer.play(walk_dir, -1, 1/seconds_per_step)
               $Tween.start()
               yield($Tween,"tween_completed")
               $AnimationPlayer.stop()
func finish_move():
    $AnimationPlayer.play(idle_dir)
    trying_to_move = false
    movement_interrupted = false

While this isn't entirely undesirable behaviour, as the title suggests I'm looking to accomplish something similar to the AStar demo in which instead of being cancelled, the destination is changed and the character paths to the new point instead. However, as the demo's movement is a bit different from mine (notably in that it doesn't use a Tween), I haven't quite been able to implement it in my own game.

With some small adjustments, I was able to get it slightly closer to the desired behaviour, but...

Quite the jittery one

Relevant code:

func _process(_delta)
        if Input.is_action_just_pressed("left_click"):
                    if trying_to_move:
                        movement_interrupted = true
                    trying_to_move = true
                    target_pos = get_global_mouse_position()
                    var path = get_parent().find_path(position, target_pos, debug_can_walk_on_water)
                    if not path.empty(): path.remove(0)

                    while not path.empty():
                        set_sprite_facing(as_direction(path[0] - position))
                        if movement_interrupted:
                            break
                        var func_var = do_move(path[0])
                        if func_var is GDScriptFunctionState: yield(func_var, "completed")

                        path.remove(0)
                    finish_move()

    (do_move and finish_move same as above)

While the character ends up in the correct place, this obviously looks horrible, and it steps over multiple cells at once. I feel like the root of the problem is the Tween but I'm at quite a loss as to how I can fix it up from here. Hopefully I've provided enough information to get some feedback, and if not, I'll do my best to explain.

Any input is much appreciated, as I'm still quite unfamiliar with the node-based structure of Godot, so my approach may be completely off the mark.

asked Mar 17 in Engine by Solipod (12 points)

Please log in or register to answer this question.

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.