forked from moyin/whale-town-front
88 lines
2.3 KiB
GDScript
88 lines
2.3 KiB
GDScript
extends CharacterBody2D
|
|
|
|
# 远程玩家脚本
|
|
# 负责处理位置同步和动画播放
|
|
# 严格遵循 Visual Only 原则:无输入处理,无物理碰撞
|
|
|
|
# 公共属性 (snake_case)
|
|
var user_id: String = ""
|
|
var target_position: Vector2 = Vector2.ZERO
|
|
|
|
# 内部状态
|
|
var last_direction: String = "down"
|
|
@onready var animation_player: AnimationPlayer = $AnimationPlayer
|
|
@onready var sprite: Sprite2D = $Sprite2D
|
|
|
|
func _ready():
|
|
# 初始化时确保无物理处理
|
|
set_physics_process(false)
|
|
# 初始位置设为当前位置
|
|
target_position = global_position
|
|
|
|
# 确保禁用物理碰撞 (双重保险)
|
|
if has_node("CollisionShape2D"):
|
|
$CollisionShape2D.disabled = true
|
|
|
|
func _process(delta: float):
|
|
# 1. 平滑移动插值
|
|
var current_pos = global_position
|
|
var dist = current_pos.distance_to(target_position)
|
|
|
|
if dist > 1.0:
|
|
# 简单的线性插值,速度系数 10.0 可根据需要调整
|
|
var new_pos = current_pos.lerp(target_position, 10.0 * delta)
|
|
|
|
# 计算移动向量用于动画朝向
|
|
var move_vec = new_pos - current_pos
|
|
_update_animation(move_vec)
|
|
|
|
global_position = new_pos
|
|
else:
|
|
# 距离很近时直接吸附并播放待机动画
|
|
global_position = target_position
|
|
_play_idle_animation()
|
|
|
|
# 统一初始化方法
|
|
# data: 包含 camelCase 字段的字典 (userId, username, position 等)
|
|
func setup(data: Dictionary):
|
|
if data.has("userId"):
|
|
user_id = data.userId
|
|
|
|
if data.has("position"):
|
|
var pos_data = data.position
|
|
if pos_data.has("x") and pos_data.has("y"):
|
|
var new_pos = Vector2(pos_data.x, pos_data.y)
|
|
global_position = new_pos
|
|
target_position = new_pos
|
|
|
|
# 如果有名字显示需求,可在此扩展
|
|
# if data.has("username") and has_node("Label"):
|
|
# $Label.text = data.username
|
|
|
|
# 更新目标位置
|
|
func update_position(new_pos: Vector2):
|
|
target_position = new_pos
|
|
|
|
# 动画更新逻辑 (复用 PlayerController 的命名规范)
|
|
func _update_animation(move_vec: Vector2):
|
|
if not animation_player:
|
|
return
|
|
|
|
# 确定主方向
|
|
if abs(move_vec.x) > abs(move_vec.y):
|
|
if move_vec.x > 0:
|
|
last_direction = "right"
|
|
else:
|
|
last_direction = "left"
|
|
else:
|
|
if move_vec.y > 0:
|
|
last_direction = "down"
|
|
else:
|
|
last_direction = "up"
|
|
|
|
animation_player.play("walk_" + last_direction)
|
|
|
|
func _play_idle_animation():
|
|
if animation_player:
|
|
animation_player.play("idle_" + last_direction)
|