Random movement

Godot Version

4.2.1

Question

In the following code, the player rotates to a random rotation by a tween and moves for a random distance. Then the player rotates again. How do I have to change the code if I want, that rotation and movement occurs simultaneously and the player always looks in the direction of the current rotation so that rotation and movement happen gradually?

extends Node

@export var speed: int = 100
@export var min_distance: int = 50
@export var max_distance: int = 300
@export var rotation_speed: float = 1.0
@export_range(-360.0, 360.0, 30.0,"degrees") var min_rotation: float = 0.0
@export_range(-360.0, 360.0, 30.0,"degrees") var max_rotation: float = 360.0

var parent: Node2D
var distance: int = 0 
var distance_to_travel: int = 0 
var direction: Vector2 = Vector2.ZERO
var target_rotation: float = 0.0 

enum STATE { IDLE, MOVING, ROTATING}
var state: STATE = STATE.MOVING

func _ready() -> void:
	parent = get_parent() as Node2D
	direction = Vector2.ZERO
	state = STATE.IDLE

func _physics_process(delta: float) -> void:
	match state:
		STATE.IDLE:
			set_random_course()
		STATE.MOVING:
			move_player(delta)


func set_random_course() -> void:
	distance = 0
	distance_to_travel = randi_range(min_distance, max_distance)
	var random_rotation = randf_range(min_rotation, max_rotation)

	state = STATE.ROTATING
	rotate_player(random_rotation, rotation_speed )

func move_player(delta):
	var old_position = parent.position
	parent.position += speed * direction * delta
	distance += abs(parent.position.distance_to(old_position))

	if distance >= distance_to_travel:
		state = STATE.IDLE

func rotate_player(target_rotation: float, rotation_speed: float):
	var tween = create_tween()
	tween.tween_property(parent, "rotation_degrees", target_rotation, rotation_speed)
	await tween.finished
	direction = Vector2.from_angle(parent.rotation).normalized()
	print("Direction: ", direction)
	state = STATE.MOVING

I am not sure if I understand exactly what you are trying to do, especially “the player always looks in the direction of the current rotation so that rotation and movement happen gradually”. But if you want rotation and movement to occur at the same time, just remove “await tween.finished”.

If you want smooth movements on a character, instead of using a tween, just have a target value and a current value and interpolate between them on each frame with lerp and angle_lerp.
That way you don’t have to deal with a new object being created every frame (the tween).