extends Node var enemy_list : Array var player : CharacterBody2D var after_image_list : Array # 存储动画状态 var stored_animations := {} # 震屏相关变量 var main_camera: Camera2D var shake_camera: Camera2D var shake_strength := 10.0 var shake_timer: Timer var shake_duration_timer: Timer # 新增:震屏持续时间计时器 var is_frozen := false func _ready() -> void: update_freeze_list() # 获取相机引用 player = get_tree().get_first_node_in_group("Player") if player: main_camera = player.get_node("Cameras/Camera") shake_camera = player.get_node("Cameras/Camera_Shake") # 确保两个相机的缩放一致 if main_camera and shake_camera: shake_camera.zoom = main_camera.zoom # 确保震屏相机初始状态是禁用的 shake_camera.enabled = false main_camera.enabled = true # 设置震屏效果计时器 shake_timer = Timer.new() add_child(shake_timer) shake_timer.wait_time = 0.01 # 确保频率够快 shake_timer.connect("timeout", _on_shake_timer_timeout) # 设置持续时间计时器 shake_duration_timer = Timer.new() add_child(shake_duration_timer) shake_duration_timer.one_shot = true shake_duration_timer.connect("timeout", stop_screen_shake) func update_freeze_list() -> void: enemy_list = get_tree().get_nodes_in_group("Enemy") player = get_tree().get_first_node_in_group("Player") after_image_list = get_tree().get_nodes_in_group("After_Image") func freeze() -> void: is_frozen = true update_freeze_list() if player: freeze_player() for enemy in enemy_list: if is_instance_valid(enemy) and not enemy.death: freeze_enemy(enemy) for after_image in after_image_list: if is_instance_valid(after_image): freeze_after_image(after_image) start_screen_shake() func unfreeze() -> void: is_frozen = false stop_screen_shake() if player: unfreeze_player() for enemy in enemy_list: #print(enemy) if is_instance_valid(enemy) and not enemy.death: unfreeze_enemy(enemy) for after_image in after_image_list: if is_instance_valid(after_image): unfreeze_after_image(after_image) ## 存储动画状态 # 存储动画的关键信息以便后续恢复 # @param animation_player - 要存储状态的动画播放器 # @param key - 用于标识该动画状态的唯一键值 func store_animation_state(animation_player: AnimationPlayer, key: String) -> void: # 存储四个关键属性: # - current_animation: 当前播放的动画名称 # - position: 动画播放到的具体位置,用于精确恢复 # - speed_scale: 动画播放速度,某些情况下可能被修改 # - is_playing: 动画是否在播放,用于区分播放/暂停状态 stored_animations[key] = { "animation": animation_player.current_animation, "position": animation_player.current_animation_position, "speed_scale": animation_player.speed_scale, "is_playing": animation_player.is_playing() } ## 恢复动画状态 func restore_animation_state(animation_player: AnimationPlayer, key: String) -> void: if stored_animations.has(key): var state = stored_animations[key] if state.animation != "": animation_player.play(state.animation) animation_player.seek(state.position, true) # 添加true参数确保更新 animation_player.set_speed_scale(state.speed_scale) # 如果原来是暂停状态,恢复后也应该暂停 if not state.is_playing: animation_player.pause() stored_animations.erase(key) ## 冻结enemy # 暂停敌人的物理处理和动画播放 # 重要:使用pause而不是stop来暂停动画,因为stop会重置动画状态 # @param enemy - 要冻结的敌人节点 func freeze_enemy(enemy: CharacterBody2D) -> void: if not is_instance_valid(enemy): return var state_machine = enemy.get_node_or_null("Enemy_State_Machine") var body_animation = enemy.get_node_or_null("Body_Animation/AnimationPlayer") # 暂停状态机的物理处理,防止状态切换和位置更新 if state_machine: state_machine.set_physics_process(false) if body_animation: var key = "enemy_" + str(enemy.get_instance_id()) # 使用实例ID确保键值唯一性 store_animation_state(body_animation, key) body_animation.pause() # 使用pause保持动画状态 ## 冻结Player # 暂停玩家的输入处理、物理处理和动画播放 # 重要:需要同时处理玩家的身体动画和攻击动画 # @param player - 玩家节点 func freeze_player() -> void: if not is_instance_valid(player): return # 禁用玩家的核心功能 player.can_attack = false #player.can_dash = false player.set_can_gameplay_input(false) var state_machine = player.get_node_or_null("Player_State_Machine") var body_animation = player.get_node_or_null("Body_Animation/AnimationPlayer") var attack_animation = player.get_node_or_null("Hit/Player_Attack_Component/AnimationPlayer") # 暂停状态机更新 if state_machine: state_machine.set_physics_process(false) # 分别存储和暂停身体动画和攻击动画 if body_animation: store_animation_state(body_animation, "player_body") body_animation.pause() if attack_animation: store_animation_state(attack_animation, "player_attack") attack_animation.pause() ## 冻结after_image func freeze_after_image(after_image: Node2D) -> void: if not is_instance_valid(after_image): return #AfterImageFreezer.freeze_after_image(after_image) var animation = after_image.get_node_or_null("AnimationPlayer") if animation: var key = "enemy_" + str(after_image.get_instance_id()) # 使用实例ID确保键值唯一性 store_animation_state(animation, key) animation.pause() # 使用pause保持动画状态 ## 解冻enemy # 恢复敌人的物理处理和动画播放 # 特殊处理:如果敌人在Hurt_Begin状态被冻结,直接切换到Hurt_Air状态 # @param enemy - 要解冻的敌人节点 func unfreeze_enemy(enemy: CharacterBody2D) -> void: if not is_instance_valid(enemy): return var state_machine = enemy.get_node_or_null("Enemy_State_Machine") var body_animation = enemy.get_node_or_null("Body_Animation/AnimationPlayer") if body_animation: var key = "enemy_" + str(enemy.get_instance_id()) # 特殊状态处理:Hurt_Begin是过渡状态,需要直接切换到Hurt_Air if stored_animations.has(key): var stored_state = stored_animations[key] if stored_state.animation == "Hurt_Begin" or enemy.freeze: restore_animation_state(body_animation, key) if state_machine: state_machine.set_physics_process(true) state_machine.change_state("hurt_air") return restore_animation_state(body_animation, key) if state_machine: state_machine.set_physics_process(true) ## 解冻Player # 恢复玩家的所有功能和动画状态 # @param player - 玩家节点 func unfreeze_player() -> void: if not is_instance_valid(player): return # 重新启用玩家的核心功能 player.can_attack = true player.can_dash = true player.set_can_gameplay_input(true) var state_machine = player.get_node_or_null("Player_State_Machine") var body_animation = player.get_node_or_null("Body_Animation/AnimationPlayer") var attack_animation = player.get_node_or_null("Hit/Player_Attack_Component/AnimationPlayer") # 恢复状态机更新 if state_machine: state_machine.set_physics_process(true) # 分别恢复身体动画和攻击动画 if body_animation: restore_animation_state(body_animation, "player_body") if attack_animation: restore_animation_state(attack_animation, "player_attack") ## 解冻After_image func unfreeze_after_image(after_image: Node2D) -> void: if not is_instance_valid(after_image): return #AfterImageFreezer.unfreeze_after_image(after_image) var animation = after_image.get_node_or_null("AnimationPlayer") if animation: var key = "enemy_" + str(after_image.get_instance_id()) # 特殊状态处理:Hurt_Begin是过渡状态,需要直接切换到Hurt_Air if stored_animations.has(key): restore_animation_state(animation, key) func start_screen_shake(strength: float = 10.0) -> void: if main_camera and shake_camera: shake_strength = strength var camera_center = main_camera.get_screen_center_position() main_camera.enabled = false shake_camera.enabled = true shake_camera.global_position = camera_center shake_camera.offset = Vector2.ZERO shake_timer.start() func start_screen_shake_with_duration(duration: float, strength: float = 10.0) -> void: start_screen_shake(strength) shake_duration_timer.wait_time = duration shake_duration_timer.start() func stop_screen_shake() -> void: if main_camera and shake_camera: shake_timer.stop() shake_duration_timer.stop() shake_camera.offset = Vector2.ZERO shake_camera.enabled = false main_camera.enabled = true # 震屏效果实现 func _on_shake_timer_timeout() -> void: if shake_camera and shake_camera.enabled: # 使用较大的随机范围 var rand_x = randf_range(-shake_strength, shake_strength) var rand_y = randf_range(-shake_strength, shake_strength) shake_camera.offset = Vector2(rand_x, rand_y) # 判断是否正在震屏 func is_shaking() -> bool: return shake_camera != null and shake_camera.enabled