diff --git a/manager/scene/scene_manager.gd b/manager/scene/scene_manager.gd index bd47a2d7..630321d5 100644 --- a/manager/scene/scene_manager.gd +++ b/manager/scene/scene_manager.gd @@ -127,22 +127,6 @@ func player_action(action_code: int, auto_quit := false): printerr("player_action: Player node not found") -func set_camera_boundary(rect: Rect2) -> void: - var camera_marker = get_camera_marker() - camera_marker.limit_left = rect.position.x - camera_marker.limit_right = rect.position.x + rect.size.x - camera_marker.limit_top = rect.position.y - camera_marker.limit_bottom = rect.position.y + rect.size.y - - -func set_player_boundary(rect: Rect2) -> void: - var player = get_player() - if player: - player.player_movement_rect = rect - else: - printerr("Player node not found") - - var debug_balloon_scene = preload("res://scene/dialog/balloon_debug.tscn") var debug_balloon_node diff --git a/scene/ground/ground.gd b/scene/ground/ground.gd index 7f4f827d..bc8d447c 100644 --- a/scene/ground/ground.gd +++ b/scene/ground/ground.gd @@ -107,10 +107,26 @@ func _restart_from_main(): get_tree().change_scene_to_file.call_deferred("res://scene/main.tscn") +func get_player() -> MainPlayer: + if player: + return player + if GlobalConfig.DEBUG: + print("[Ground] get_player before ready") + return get_node_or_null("MainPlayer") as MainPlayer + + +func get_camera() -> CameraFocusMarker: + if camera_focus_marker: + return camera_focus_marker + if GlobalConfig.DEBUG: + print("[Ground] get_camera before ready") + return get_node_or_null("CameraFocusMarker") as CameraFocusMarker + + func reset_player_y(): # 从屏幕下边缘算起 if player_y_fixed: - player.set_y_from_ground(158.0 - player_y) + get_player().set_y_from_ground(158.0 - player_y) func _set_camera_and_player_boundary(): @@ -128,11 +144,16 @@ func _set_camera_and_player_boundary(): # player rect should be set centered, with 30px x padding player_rect.position.x = player_line.get_point_position(0).x + player_line.global_position.x player_rect.size.x = player_line.get_point_position(1).x - player_line.get_point_position(0).x - SceneManager.set_camera_boundary(camera_rect) - SceneManager.set_player_boundary(player_rect) if GlobalConfig.DEBUG: - print("_set_camera_and_player_boundary:", camera_rect, player_rect) - + print("try to _set_camera_and_player_boundary as:", camera_rect, player_rect) + # set_camera_boundary + var camera_marker = get_camera() + camera_marker.limit_left = camera_rect.position.x + camera_marker.limit_right = camera_rect.position.x + camera_rect.size.x + camera_marker.limit_top = camera_rect.position.y + camera_marker.limit_bottom = camera_rect.position.y + camera_rect.size.y + # set_player_boundary + get_player().player_movement_rect = player_rect func _load_footstep_audio(): # foot step sound @@ -150,22 +171,20 @@ func play_footstep_sound() -> void: func move_player_to_portal(portal_name: String) -> void: var node_path = NodePath("DeployLayer/portal_" + portal_name) var portal_node = get_node_or_null(node_path) as Portal2D - if portal_node and player: - player.global_position.x = portal_node.global_position.x + var mov_player = get_player() as MainPlayer + if portal_node and mov_player: + mov_player.global_position.x = portal_node.global_position.x if portal_name == "left": - player.set_facing_direction(Vector2.RIGHT) + mov_player.set_facing_direction(Vector2.RIGHT) elif portal_name == "right": - player.set_facing_direction(Vector2.LEFT) + mov_player.set_facing_direction(Vector2.LEFT) reset_player_y() if GlobalConfig.DEBUG: print("move player to portal:", portal_name, portal_node.global_position) - elif player: + elif mov_player: printerr(scene_name, " portal not found: ", node_path) else: printerr("move_player_to_portal player not ready") - # 传送后,重置 camera 位置 - if not Engine.is_editor_hint(): - camera_focus_marker.reset_position_immediately() func _setup_player_light(): diff --git a/scene/ground/ground_loader.gd b/scene/ground/ground_loader.gd index efd40c40..5fc031ff 100644 --- a/scene/ground/ground_loader.gd +++ b/scene/ground/ground_loader.gd @@ -76,10 +76,11 @@ func _ready() -> void: var display_start_sec = 0.0 + # wait_time 包含 ease in + wait + ease out 完整时长 # ease duration = min(ease_min_duration, wait_time * 0.5) func toggle_mask( - display: bool, wait_time: float, ease_min_duration := 0.3, mask_color:= Color.BLACK + display: bool, wait_time: float, ease_min_duration := 0.3, mask_color := Color.BLACK ) -> Tween: var tween = get_tree().create_tween() mask_color.a = mask.color.a @@ -112,9 +113,7 @@ func _load_save(): entrance_portal = ArchiveManager.archive.entrance_portal -func transition_to_scene( - scene_name: String, portal: String, wait_time := 1.4 -) -> void: +func transition_to_scene(scene_name: String, portal: String, wait_time := 1.4) -> void: if ground: print("GroundLoader transition_to_scene: pause prev ground.") ground.process_mode = Node.PROCESS_MODE_DISABLED @@ -134,9 +133,7 @@ func transition_to_scene( tween.tween_callback(_do_transition.call_deferred.bind(scene_name)) _allow_ground_start = false # 等到 toggle_mask 结束,再重置 freeze 状态 - toggle_mask(false, wait_time).tween_callback( - func(): _allow_ground_start = true - ) + toggle_mask(false, wait_time).tween_callback(func(): _allow_ground_start = true) else: _allow_ground_start = true _do_transition.call_deferred(scene_name) @@ -197,8 +194,8 @@ func _do_transition(scene_name: String) -> void: func _add_ground(): ground.ready.connect(SceneManager.ground_ready.emit.bind(ground)) - add_child(ground) ground.name = "Ground" + # 在 add child 之前,调整 ground 内部元素属性,在 on ground ready 前设置完成 if not Engine.is_editor_hint(): # 更新玩家位置 if not has_entered: @@ -206,18 +203,27 @@ func _add_ground(): else: # move player to portal ground.move_player_to_portal(entrance_portal) + if GlobalConfig.DEBUG: + print( + "GroundLoader add_ground finished:", + ground.scene_name, + " player.pos=", + ground.get_player().global_position + ) + add_child(ground) + # ready 后,再整体重置 camera 位置 + if not Engine.is_editor_hint(): + ground.get_camera().reset_position_immediately() has_entered = true func _update_player_position_from_archive(): if ignore_archive or Engine.is_editor_hint(): return - var player = SceneManager.get_player() as MainPlayer + var player = ground.get_player() as MainPlayer player.global_position.x = ArchiveManager.archive.player_global_position_x player.set_facing_direction(ArchiveManager.archive.player_direction) ground.reset_player_y() - # 传送后,重置 camera 位置 - ground.camera_focus_marker.reset_position_immediately() func _load_ground_node(scene_name: String) -> Ground2D: diff --git a/scene/ground/scene/c02/s03_院子.gd b/scene/ground/scene/c02/s03_院子.gd index 9985ea2d..9b913bac 100644 --- a/scene/ground/scene/c02/s03_院子.gd +++ b/scene/ground/scene/c02/s03_院子.gd @@ -309,7 +309,9 @@ func run_away(): var node = burning_layer.get_node("牵手跑") as Node2D var sprite_together = node.get_node("牵手跑动画") as AnimatedSprite2D node.visible = true - SceneManager.get_camera_marker().focus_node(sprite_together) + var camera = SceneManager.get_camera_marker() + camera.focus_node(sprite_together) + create_tween().tween_property(camera, "force_offset:x", -200.0, 10.0) player.reparent_light(sprite_together) # 牵手动作 var sprite_xiaochan = burning_layer.get_node("Ambush等待的小蝉/小婵呼吸") @@ -325,4 +327,5 @@ func run_away(): await tween.finished # 1: 牵手跑结束; 2: 谢幕演出结束 EventManager.set_stage(&"c02_burning_end", 1) + camera.force_offset.x = 0.0 SceneManager.get_ground_loader().transition_to_scene("c02_s06", "right") diff --git a/scene/ground/scene/c02/s12_盒子猫.gd b/scene/ground/scene/c02/s12_盒子猫.gd index c3f755e2..6a964760 100644 --- a/scene/ground/scene/c02/s12_盒子猫.gd +++ b/scene/ground/scene/c02/s12_盒子猫.gd @@ -22,14 +22,14 @@ func _on_ground_ready() -> void: print("[盒子猫] intro start") SceneManager.lock_player() player.hide_sprite = true - player.position.x = 231.0 + player.position.x = 232.0 var layer = $"../盒子猫CanvasLayer" layer.disable_crawl = true var duration = layer.show_cat_duration await get_tree().create_timer(duration).timeout - $"Sfx钻盒子演出".play() var camera = SceneManager.get_camera_marker() - create_tween().tween_property(camera, "force_offset", Vector2.ZERO, 1.0) + create_tween().tween_property(camera, "force_offset", Vector2.ZERO, 1.5) + $"Sfx钻盒子演出".play() anim.play() await anim.animation_finished layer.disable_crawl = false diff --git a/scene/ground/scene/c02/s12_盒子猫.tscn b/scene/ground/scene/c02/s12_盒子猫.tscn index 7222e336..76e29c10 100644 --- a/scene/ground/scene/c02/s12_盒子猫.tscn +++ b/scene/ground/scene/c02/s12_盒子猫.tscn @@ -47,12 +47,12 @@ position = Vector2(465, 21) [node name="小猫初始动画" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="2"] process_mode = 1 -position = Vector2(211, 3) +position = Vector2(212, 3) sprite_frames = ExtResource("5_ycgng") animation = &"猫钻进盒子" [node name="MainPlayer" parent="Ground" index="5"] -position = Vector2(231, 71) +position = Vector2(232, 71) character = "盒子猫" facing_direction = Vector2(1, 0) diff --git a/scene/ground/script/c02/盒子猫canvas_layer.gd b/scene/ground/script/c02/盒子猫canvas_layer.gd index f38248af..fc588f79 100644 --- a/scene/ground/script/c02/盒子猫canvas_layer.gd +++ b/scene/ground/script/c02/盒子猫canvas_layer.gd @@ -25,7 +25,7 @@ func _ready(): cat_fg.visible = true var tween = create_tween() tween.tween_interval(2.5) - tween.tween_property(cat_fg, "modulate:a", 0.0, show_cat_duration - 3) + tween.tween_property(cat_fg, "modulate:a", 0.0, show_cat_duration - 2.5) else: cat_fg.visible = false @@ -34,6 +34,8 @@ var down_pressing = false: set(val): if down_pressing == val: return + if disable_crawl and val: + return down_pressing = val _try_toggle_crawl() diff --git a/scene/ground/script/c02/盒子猫canvas_layer.tscn b/scene/ground/script/c02/盒子猫canvas_layer.tscn index 5fb45b5d..aa677013 100644 --- a/scene/ground/script/c02/盒子猫canvas_layer.tscn +++ b/scene/ground/script/c02/盒子猫canvas_layer.tscn @@ -13,6 +13,7 @@ [ext_resource type="Texture2D" uid="uid://dx3i8mchgux1d" path="res://asset/art/scene/c02/s12_to_s17_盒子猫/ux_纸张.png" id="6_rxlkc"] [node name="盒子猫CanvasLayer" type="CanvasLayer"] +process_mode = 1 layer = 0 script = ExtResource("1_ygosu") diff --git a/scene/ground/script/c02/追猫猪头怪.gd b/scene/ground/script/c02/追猫猪头怪.gd index 553758d2..f7597355 100644 --- a/scene/ground/script/c02/追猫猪头怪.gd +++ b/scene/ground/script/c02/追猫猪头怪.gd @@ -106,8 +106,9 @@ func _on_footstep_timer_timeout() -> void: footstep_count += 1 if footstep_count % 2 == 0: # shake camera - camera.shake_camera() - if abs(signed_x_diff) > 250: + var strength = 0.5 + 1.5 * smoothstep(300, 5, abs(signed_x_diff)) + camera.shake_camera(strength, 1.0) + if abs(signed_x_diff) > 300: if footstep_count % 3 == 0: sfx_footstep.play() elif abs(signed_x_diff) > 100: