盒子猫细节优化, Ground 加载先传送/更新玩家位置,再add触发ready

This commit is contained in:
cakipaul 2025-07-01 11:39:25 +08:00
parent 1e335a96c4
commit 4cb89de3d7
9 changed files with 65 additions and 49 deletions

View File

@ -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

View File

@ -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():

View File

@ -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:

View File

@ -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")

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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")

View File

@ -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: