创建新工程
This commit is contained in:
210
scripts/DebugCamera.gd
Normal file
210
scripts/DebugCamera.gd
Normal file
@@ -0,0 +1,210 @@
|
||||
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
|
||||
Reference in New Issue
Block a user