69 lines
2.6 KiB
GDScript
69 lines
2.6 KiB
GDScript
extends Node2D
|
|
|
|
## 2026-07-07 视差修正:当前美术图里地面/步道和远景烙在同一张图上。
|
|
## 为了让角色脚下参照物保持 1:1 世界坐标,ArtLayer 先作为 WorldGroundLayer
|
|
## 固定不随相机做视差。未来美术拆出天空/夕阳后,把远景节点放入
|
|
## SkyParallaxLayer,即可继续按 0.2 倍世界滚动(80% 跟随相机)。
|
|
## 勿用 Parallax2D(历史上因 CanvasModulate/wipe 兼容性移除过,见 decisions.md)。
|
|
const PARALLAX_SCROLL_SCALE := 0.2
|
|
const PARALLAX_ANCHOR_X := 1734.5
|
|
|
|
@onready var past_background: CanvasItem = $ArtLayer/PastBackground
|
|
@onready var future_background: CanvasItem = $ArtLayer/FutureBackground
|
|
@onready var _world_ground_layer: Node2D = $ArtLayer
|
|
@onready var _sky_parallax_layer: Node2D = get_node_or_null("SkyParallaxLayer") as Node2D
|
|
|
|
var _world_ground_base_x := 0.0
|
|
var _sky_parallax_base_x := 0.0
|
|
|
|
|
|
func _ready() -> void:
|
|
_world_ground_base_x = _world_ground_layer.position.x
|
|
if _sky_parallax_layer != null:
|
|
_sky_parallax_base_x = _sky_parallax_layer.position.x
|
|
_set_time_phase(_current_time_phase())
|
|
var bus := _event_bus_or_null()
|
|
if bus != null and bus.has_signal("time_phase_changed") and not bus.is_connected("time_phase_changed", _on_time_phase_changed):
|
|
bus.connect("time_phase_changed", _on_time_phase_changed)
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
_world_ground_layer.position.x = _world_ground_base_x
|
|
if _sky_parallax_layer == null:
|
|
return
|
|
var camera := get_viewport().get_camera_2d()
|
|
if camera == null:
|
|
# headless 测试/无相机场景:远景层也保持原位。
|
|
_sky_parallax_layer.position.x = _sky_parallax_base_x
|
|
return
|
|
# get_screen_center_position 含 limit 夹取,玩家贴墙时远景不会继续滑。
|
|
var center_x := camera.get_screen_center_position().x
|
|
_sky_parallax_layer.position.x = _sky_parallax_base_x + (center_x - PARALLAX_ANCHOR_X) * (1.0 - PARALLAX_SCROLL_SCALE)
|
|
|
|
|
|
func _on_time_phase_changed(_previous: StringName, current: StringName, _reason: StringName) -> void:
|
|
_set_time_phase(current)
|
|
|
|
|
|
func _set_time_phase(time_phase: StringName) -> void:
|
|
var use_future := time_phase == &"future"
|
|
if past_background != null:
|
|
past_background.visible = not use_future
|
|
if future_background != null:
|
|
future_background.visible = use_future
|
|
|
|
|
|
func _current_time_phase() -> StringName:
|
|
if not is_inside_tree():
|
|
return &"past"
|
|
var manager := get_tree().root.get_node_or_null("TimePhaseManager")
|
|
if manager != null:
|
|
return StringName(str(manager.get("current_time_phase")))
|
|
return &"past"
|
|
|
|
|
|
func _event_bus_or_null() -> Node:
|
|
if not is_inside_tree():
|
|
return null
|
|
return get_tree().root.get_node_or_null("EventBus")
|