0 votes

Hi, I'm new to Godot, and I'm starting to learn how to use it, following different guides. For now, I've created a Player with eight different running animations (eight directions). Granted, I know that at the moment the script is probably very dirty (definitely), but at the moment I'm interested in learning. To clean it there is time to do it...

extends KinematicBody2D

const floor_normal : = Vector2(0, -1)

var speed : = 10000.0
var del : = 0.2
var velocity : = Vector2()
var target_speed_x : = 0.0
var target_speed_y : = 0.0

var directions : = "south"

onready var anim_sprite : = $anim_sprite as AnimatedSprite

func _process(delta):
    #print(directions)
    if velocity.x == 0 && velocity.y == 0:
        if anim_sprite.animation == "run_"+directions && anim_sprite.frame == anim_sprite.frames.get_frame_count("run_"+directions)-1:
            anim_sprite.play("idle_"+directions)
    else:
        anim_sprite.play("run_"+directions)

func _physics_process(delta):
    get_input(delta)

    velocity.x = lerp(velocity.x, target_speed_x, del)
    if abs(velocity.x) < 1:
        velocity.x = 0
    velocity.y = lerp(velocity.y, target_speed_y, del)
    if abs(velocity.y) < 1:
        velocity.y = 0
    velocity = move_and_slide(velocity, floor_normal)
    #print(velocity)

    var north = Input.is_action_pressed("ui_up")
    var south = Input.is_action_pressed("ui_down")
    var west = Input.is_action_pressed("ui_left")
    var east = Input.is_action_pressed("ui_right")

    var direction = Vector2()

    if north:
        direction += Vector2(0, 1)
    if south:
        direction += Vector2(0, -1)
    if west:
        direction += Vector2(-1, 0)
    if east:
        direction += Vector2(1, 0)
    direction = direction.normalized()

    var angle = rad2deg(direction.angle())
    if angle >= 0:
        angle = angle
    else:
        angle + 360

    if int(angle) == 0:
        directions = "east"
    elif int(angle) == -45:
        directions = "south_east"
    elif int(angle) == -90:
        directions = "south"
    elif int(angle) == -135:
        directions = "south_west"
    elif int(angle) == 180:
        directions = "west"
    elif int(angle) == 135:
        directions = "north_west"
    elif int(angle) == 90:
        directions = "north"
    elif int(angle) == 45:
        directions = "north_east"
    else:
        directions = "south"

func get_input(delta):
    target_speed_x = (Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")) * speed * delta
    target_speed_y = (Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")) * speed * delta

I currently have three problems that I can't solve...

  1. When I release the movement commands, the sprite's direction is set to east. This is caused by the angle returning to 0. What I would like instead is that the direction remain the same as it was set (so if the direction of the sprite moving was south, once released the key must stay south)
  2. At the moment I'm using a sprite and animation from the Factorio game as a placeholder, as I haven't found many eight-way sprites on the net. The running animation consists of 22 frames. What happens at the moment is that if I release the run button, the sprite continues to run in place until the animation ends. What I would like instead is that the sprite continue to move in the current direction until the animation ends (even if the key has been released)
  3. The speed of the sprite diagonally increases with respect to the vertical or horizontal direction. How can I make it the same instead?

Thanks for your help.

Godot version 3.2.3
in Engine by (15 points)

1 Answer

0 votes
  1. You need variable to save last movement direction. Use this variable to set player's facing direction.
  2. Hook animation_finished and stop player inside this signal, instead of key release.
  3. You need to clean your code, because you repeat your code like 2 or 3 times. You need to have normalized direction vector and then multiply it by speed.
    var direction = Vector2(Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left"), Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")).normalized() var velocity = direction * speed
    and then you can call move_and_slide with velocity.

Also note that
moveandslide - linearvelocity is the velocity vector (typically meters per second). Unlike in moveand_collide(), you should not multiply it by delta — the physics engine handles applying the velocity.

by (1,466 points)
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 Frequently asked questions and 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 [email protected] with your username.