extends Camera2D ## 调试相机控制 ## 用于在测试场景时移动相机查看不同区域 # 相机移动速度 var move_speed = 500.0 var zoom_speed = 1.2 # 大幅增加缩放速度,让Q/E响应更快 # 最小和最大缩放 var min_zoom = 0.3 var max_zoom = 2.0 # 重置动画相关 var is_resetting = false var reset_target_position = Vector2.ZERO var reset_target_zoom = Vector2.ONE var reset_duration = 1.2 # 进一步增加重置动画时间,让动画更慢更优雅 # 流畅滚轮缩放相关 var scroll_velocity = 0.0 # 当前滚轮速度 var scroll_acceleration = 0.0 # 滚轮加速度 var scroll_friction = 8.0 # 摩擦力,控制减速 var scroll_sensitivity = 0.8 # 滚轮敏感度 var max_scroll_speed = 3.0 # 最大滚轮速度 var zoom_smoothness = 12.0 # 缩放平滑度 var current_target_zoom = 1.0 # 当前目标缩放值 # UI状态检测 var ui_focused = false func _ready(): print("Debug Camera Controls:") print(" WASD / Arrow Keys - Move camera") print(" Mouse Wheel - Zoom in/out (smooth)") print(" R - Reset camera position") # 初始化目标缩放值 current_target_zoom = zoom.x func _process(delta): # 如果正在重置,跳过手动控制 if is_resetting: return # 检查UI焦点状态 _update_ui_focus_status() # 处理流畅滚轮缩放 _update_smooth_zoom(delta) # 相机移动(只有在UI未获得焦点时) var move_direction = Vector2.ZERO if not ui_focused: # WASD 或方向键移动 if Input.is_action_pressed("ui_right") or Input.is_key_pressed(KEY_D): move_direction.x += 1 if Input.is_action_pressed("ui_left") or Input.is_key_pressed(KEY_A): move_direction.x -= 1 if Input.is_action_pressed("ui_down") or Input.is_key_pressed(KEY_S): move_direction.y += 1 if Input.is_action_pressed("ui_up") or Input.is_key_pressed(KEY_W): move_direction.y -= 1 # 重置相机 if Input.is_action_just_pressed("ui_accept") or Input.is_key_pressed(KEY_R): reset_camera_smooth() # 应用移动 if move_direction.length() > 0: move_direction = move_direction.normalized() position += move_direction * move_speed * delta func _input(event): # 流畅鼠标滚轮缩放 if event is InputEventMouseButton: if event.button_index == MOUSE_BUTTON_WHEEL_UP: _add_scroll_impulse(scroll_sensitivity) elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN: _add_scroll_impulse(-scroll_sensitivity) func zoom_camera(amount: float): """缩放相机(平滑缩放,避免颠簸)""" var new_zoom = zoom.x + amount new_zoom = clamp(new_zoom, min_zoom, max_zoom) # 使用短暂的平滑动画来避免突兀的缩放 var tween = create_tween() tween.tween_property(self, "zoom", Vector2(new_zoom, new_zoom), 0.05) tween.set_ease(Tween.EASE_OUT) tween.set_trans(Tween.TRANS_QUART) func _add_scroll_impulse(impulse: float): """添加滚轮冲量,实现流畅缩放""" # 根据滚轮滑动距离调整速度(滑动越远,速度越快) var speed_multiplier = abs(impulse) * 1.5 + 1.0 scroll_velocity += impulse * speed_multiplier # 限制最大滚轮速度 scroll_velocity = clamp(scroll_velocity, -max_scroll_speed, max_scroll_speed) func _update_smooth_zoom(delta: float): """更新流畅缩放效果""" # 如果有滚轮速度,更新目标缩放值 if abs(scroll_velocity) > 0.01: # 根据速度更新目标缩放 var zoom_change = scroll_velocity * delta * 2.0 current_target_zoom += zoom_change current_target_zoom = clamp(current_target_zoom, min_zoom, max_zoom) # 应用摩擦力减速 scroll_velocity = lerp(scroll_velocity, 0.0, scroll_friction * delta) else: # 速度很小时直接停止 scroll_velocity = 0.0 # 平滑插值到目标缩放值 var current_zoom = zoom.x var new_zoom = lerp(current_zoom, current_target_zoom, zoom_smoothness * delta) # 只有当缩放值有明显变化时才更新 if abs(new_zoom - current_zoom) > 0.001: zoom = Vector2(new_zoom, new_zoom) func reset_camera(): """重置相机到初始位置(立即)""" position = Vector2(640, 360) zoom = Vector2(1.0, 1.0) current_target_zoom = 1.0 scroll_velocity = 0.0 print("Camera reset to default position") func reset_camera_smooth(): """平滑重置相机到初始位置""" if is_resetting: return # 如果已经在重置中,忽略 # 检查是否有跟随的角色 var player_character = _find_player_character() if player_character: # 如果有玩家角色,重置到角色位置 reset_target_position = player_character.global_position print("Resetting camera to player position: ", reset_target_position) else: # 否则重置到默认位置 reset_target_position = Vector2(640, 360) print("Resetting camera to default position: ", reset_target_position) reset_target_zoom = Vector2(1.0, 1.0) # 创建平滑动画 is_resetting = true var tween = create_tween() tween.set_parallel(true) # 允许同时进行位置和缩放动画 # 位置动画 - 使用更平滑的缓动效果 var position_tween = tween.tween_property(self, "position", reset_target_position, reset_duration) position_tween.set_ease(Tween.EASE_OUT) # 开始快,结束慢,更自然 position_tween.set_trans(Tween.TRANS_CUBIC) # 使用三次方过渡,更平滑 # 缩放动画 - 同样使用平滑缓动效果 var zoom_tween = tween.tween_property(self, "zoom", reset_target_zoom, reset_duration) zoom_tween.set_ease(Tween.EASE_OUT) # 开始快,结束慢,更自然 zoom_tween.set_trans(Tween.TRANS_CUBIC) # 使用三次方过渡,更平滑 # 动画完成后的回调 tween.finished.connect(_on_reset_finished) func _on_reset_finished(): """重置动画完成回调""" is_resetting = false current_target_zoom = reset_target_zoom.x scroll_velocity = 0.0 print("Camera reset animation completed") func _update_ui_focus_status(): """更新UI焦点状态""" ui_focused = _is_ui_focused() func _is_ui_focused() -> bool: """ 检查是否有UI控件获得焦点(如输入框) @return: 是否有UI控件获得焦点 """ var focused_control = get_viewport().gui_get_focus_owner() # 如果有控件获得焦点,且是输入类控件,则认为UI处于活动状态 if focused_control: return focused_control is LineEdit or focused_control is TextEdit return false func _find_player_character() -> Node2D: """查找玩家角色""" # 尝试从场景树中找到玩家角色 var main_scene = get_tree().root.get_node_or_null("Main") if main_scene: # 查找 GameWorld 下的角色 var game_world = main_scene.get_node_or_null("GameWorld") if game_world: # 查找 DatawhaleOffice 场景 var office_scene = game_world.get_child(0) if game_world.get_child_count() > 0 else null if office_scene: # 查找 Characters 容器 var characters_container = office_scene.get_node_or_null("Characters") if characters_container and characters_container.get_child_count() > 0: # 返回第一个角色(通常是玩家) return characters_container.get_child(0) return null