fix: repair parallax collisions and add play guide

This commit is contained in:
wxm
2026-07-06 23:51:59 -07:00
parent 8cca00d0da
commit af7b580691
12 changed files with 921 additions and 618 deletions
+5 -1
View File
@@ -21,6 +21,10 @@ script = ExtResource("1_ground_background")
[node name="GroundAnchor" type="Marker2D" parent="."]
position = Vector2(2047, 560)
[node name="SkyParallaxLayer" type="Node2D" parent="."]
position = Vector2(896.5, 0)
z_index = -11
[node name="ArtLayer" type="Node2D" parent="."]
position = Vector2(896.5, 0)
z_index = -10
@@ -56,4 +60,4 @@ position = Vector2(3213.5, 150)
collision_mask = 0
[node name="CollisionShape2D" type="CollisionShape2D" parent="RightBoundaryBody"]
shape = SubResource("RectangleShape2D_right_boundary")
shape = SubResource("RectangleShape2D_right_boundary")
+20 -18
View File
@@ -1,27 +1,26 @@
extends Node2D
## 2026-07-06 视差定案(策划:远景夕阳要时刻在画面内):背景是"远景天幕",
## 仅以 0.2 倍速随世界滚动(即 80% 跟随相机)——此前 0.92/0.8 的"近景层"
## 参数方向反了,背景几乎钉在世界上,所以一直"看不出视差"。
## 锚点 1734.5 = 让夕阳(原画 x≈760,世界 x≈1656)在出生点镜头(可见中心
## 1340.8)恰好居中;相机全程 [1340.8, 2753.2] 内夕阳屏幕位置从中心缓移到
## 左 282px,始终在画面内(已验算含光晕不出屏)。两端背景覆盖也已验算:
## 极左窗 [880,1801.6]⊂[581.5,2882.5]、极右窗 [2292.4,3214]⊂[1711.5,4012.5]。
## 已知取舍:步道砖烙在原画里会明显随镜头走(角色脚下滑动感),单张烙死图
## 无解;美术把"近景步道"拆成独立 1:1 层后即可消除。勿用 Parallax2D
## (历史上因 CanvasModulate/wipe 兼容性移除过,见 decisions.md)。
## 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 _art_layer: Node2D = $ArtLayer
@onready var _world_ground_layer: Node2D = $ArtLayer
@onready var _sky_parallax_layer: Node2D = get_node_or_null("SkyParallaxLayer") as Node2D
var _art_base_x := 0.0
var _world_ground_base_x := 0.0
var _sky_parallax_base_x := 0.0
func _ready() -> void:
_art_base_x = _art_layer.position.x
_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):
@@ -29,14 +28,17 @@ func _ready() -> void:
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 测试/无相机场景:背景保持原位。
_art_layer.position.x = _art_base_x
# headless 测试/无相机场景:远景层也保持原位。
_sky_parallax_layer.position.x = _sky_parallax_base_x
return
# get_screen_center_position 含 limit 夹取,玩家贴墙时景不会继续滑。
# get_screen_center_position 含 limit 夹取,玩家贴墙时景不会继续滑。
var center_x := camera.get_screen_center_position().x
_art_layer.position.x = _art_base_x + (center_x - PARALLAX_ANCHOR_X) * (1.0 - PARALLAX_SCROLL_SCALE)
_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:
@@ -63,4 +65,4 @@ func _current_time_phase() -> StringName:
func _event_bus_or_null() -> Node:
if not is_inside_tree():
return null
return get_tree().root.get_node_or_null("EventBus")
return get_tree().root.get_node_or_null("EventBus")