extends CharacterBody3D

## 角色的质量，单位 kg
const weight := 60
## 角色前进的动力,同样先简化处理，单位 N
const power := 800
## 一个最简单的阻尼系数[br]
## 阻力计算公式 速度² × 阻尼系数[br]
## 假设最高速度是慢跑 10km/h , 2.77m/s，那么阻力需要在这个速度下维持和动力平衡。也就是...104.3
const damping := 104.3
## 最后一次计算之后的，当前运动状态的向量
var last_vector = Vector3.ZERO

var fall_acceleration = 75

var target_velocity = Vector3.ZERO

func _physics_process(delta: float) -> void:
	# 指令方向
	var cmd_vector_direction := get_cmd_vector()
	# 运动方向
	var pre_vector_direction = last_vector.normalized()
	# 计算当前运动状态，方向在上一步已经更新过了。剩下的是模量问题。
	# 指令力
	var cmd_vector_power = cmd_vector_direction * power
	# 阻力
	var damping_vector = -pre_vector.normalized() * last_vector.length_squared() * damping
		
	# 若指令方向和运动方向不同，则必然会产生
	if cmd_vector_direction != pre_vector_direction:
		pre_vector_direction = (pre_vector_direction + cmd_vector_direction).normalized()
		$pivot.basis = Basis.looking_at(pre_vector_direction)
	# 速度计算部分
	#target_velocity.x = direction.x * now_speed
	#target_velocity.z = direction.z * now_speed
	
	if !is_on_floor():
		target_velocity.y = target_velocity.y - ( fall_acceleration * delta )
	
	velocity = target_velocity
	move_and_slide()
	
## 获取当前指令的关联向量[br]
## 难道需要两层才生效？
func get_cmd_vector() -> Vector3:
	var vector := Vector3.ZERO
	if Input.is_action_pressed("move_forward"):
		vector.z -= 1
	if Input.is_action_pressed("move_back"):
		vector.z += 1
	if Input.is_action_pressed("move_left"):
		vector.x -= 1
	if Input.is_action_pressed("move_right"):
		vector.x += 1
	return vector.normalized()
	
