diff --git a/game/presentation/views/board_view.gd b/game/presentation/views/board_view.gd index 34c30961..aa78e702 100644 --- a/game/presentation/views/board_view.gd +++ b/game/presentation/views/board_view.gd @@ -60,8 +60,9 @@ const HERO_FRAME_PX := 32.0 # 英雄帧画布边长(素材 32×32 锁定— const HERO_SPRITE_SCALE := 1.5 # 1.5× 档(2026-09-26 用户二裁:实机看 1× 偏小放大 1.5 倍——明示 # 裁决压圣经 §8.2「禁非整数缩放」一般规则,§8.2 豁免注记归 art-bible # 批另落;头可越格上沿不裁剪) -const HERO_GROUND_FRAC := 0.75 # 脚锚纵向落点 = 格高 75%(自格顶起;即「脚在格子 1/4 处」自底边量—— - # 2026-09-26 用户裁决:不完全居中、脚踩 1/4 线,头越上格沿造立体感) +const HERO_GROUND_FRAC := 0.25 # 脚锚纵向落点 = 格底往上 25%(用户口径「脚踩格子 1/4 处·从下往上数」; + # 头越上格沿造立体感。⚠ 参照系纪律:本值一律自底边起算——上一批用 + # 「自顶 75%」表述同线异名,措辞口径误导用户被纠,本批统一为自底边) const HERO_MOVE_S := 0.14 # 位移时长(~140ms) const HERO_STEP_S := 0.18 # 走路帧周期 = 原地撞墙帧闪时长(~180ms) const HERO_DIG_S := 0.15 # 挖掘弹跳总时长(~150ms,半程压半程回) @@ -345,10 +346,10 @@ func cell_origin(c: Vector2i) -> Vector2: # 英雄脚底锚点——**世界坐标**(精灵在 SubViewport 世界内:格原点 = 格×步距,禁带壳层居中偏移。 # 2026-09-26 修正:上批误用壳层 cell_origin(含 _svp_container.position 居中偏移)定位世界内精灵, # 实测整体右偏 ~7 格+偏离格心——实机截图用户报缺陷)。 -# 纵向 = 格高 75% 线(脚踩格子 1/4 处·自底边量——2026-09-26 用户二裁);横向格中线。身体向上延伸, +# 纵向 = 格底往上 25% 线(脚踩格子 1/4 处——2026-09-26 用户裁决);横向格中线。身体向上延伸, # 头越上格沿不裁剪(立体感裁决);锚点与精灵缩放解耦(缩放只改身体向上长多少)。 func _hero_feet(c: Vector2i) -> Vector2: - return Vector2(c) * (_cell + float(SEP)) + Vector2(_cell * 0.5, _cell * HERO_GROUND_FRAC) + return Vector2(c) * (_cell + float(SEP)) + Vector2(_cell * 0.5, _cell * (1.0 - HERO_GROUND_FRAC)) # 英雄持握手位(fx 同层坐标系 = 壳层坐标——fx 在 SubViewport 之外,须含 _svp_container.position diff --git a/game/presentation/views/board_world.gd b/game/presentation/views/board_world.gd index fbdcff47..791c02a9 100644 --- a/game/presentation/views/board_world.gd +++ b/game/presentation/views/board_world.gd @@ -42,7 +42,7 @@ func ensure_hero(tex: Texture2D, shadow_px: Vector2, scale: float) -> Sprite2D: shadow.modulate = Color(0, 0, 0, 0.35) shadow.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR shadow.scale = shadow_px / (64.0 * scale) # 子件缩放叠父件 scale——目标屏幕尺寸 ÷ (纹理边 × 父档) - shadow.position = Vector2(0.0, 2.0) # 脚线下 2px——贴地接触感 + shadow.position = Vector2.ZERO # 椭圆中心 = 脚锚点(贴脚——上批 (0,2) 下坠让影子与脚脱开,用户报缺陷) shadow.z_index = -1 # 相对父件回落:格面(z=0 树序在先)之上、英雄本体之下 shadow.use_parent_material = true # 随英雄链世界去饱和材质 hero = Sprite2D.new() diff --git a/game/smoke/ui_input_probe.gd b/game/smoke/ui_input_probe.gd index eb26fa97..31f0661d 100644 --- a/game/smoke/ui_input_probe.gd +++ b/game/smoke/ui_input_probe.gd @@ -122,14 +122,15 @@ func _ready() -> void: if not ms.is_revealed(dig_t): _problems.append("case⑥ 核心揭格未落位(目标=%s)" % dig_t) # ---- case⑦ 英雄精灵世界落位(棋盘小人贴图批回归闸 2026-09-26):精灵在 SubViewport 世界内, - # 落位 = 格×步距 + 脚底锚(横=格中线/纵=格高 75% 线——2026-09-26 二裁「脚踩格子 1/4 处」; - # 禁带壳层 _svp_container.position 居中偏移——上批误用壳层 cell_origin 实测右偏 ~7 格+偏离 - # 格心,实机截图用户报缺陷)。素材缺位树(hero==null,字形「人」回退在役)跳过;断言前等 - # 0.3s 墙钟——headless 帧率无上限,帧数等待 < 位移 Tween 140ms 时会采到半途位置(首跑实证)。 ---- + # 落位 = 格×步距 + 脚底锚(横=格中线/纵=格底往上 25% 线=HERO_GROUND_FRAC 自底边口径——「脚踩 + # 格子 1/4 处·从下往上数」;禁带壳层 _svp_container.position 居中偏移——上批误用壳层 + # cell_origin 实测右偏 ~7 格+偏离格心,实机截图用户报缺陷)。素材缺位树(hero==null,字形 + # 「人」回退在役)跳过;断言前等 0.3s 墙钟——headless 帧率无上限,帧数等待 < 位移 Tween + # 140ms 时会采到半途位置(首跑实证)。 ---- if bv._world.hero != null: await get_tree().create_timer(0.3).timeout var expect: Vector2 = Vector2(ms.hero_pos()) * (bv.cell_size + float(bv.SEP)) \ - + Vector2(bv.cell_size * 0.5, bv.cell_size * bv.HERO_GROUND_FRAC) + + Vector2(bv.cell_size * 0.5, bv.cell_size * (1.0 - bv.HERO_GROUND_FRAC)) if bv._world.hero.position.distance_to(expect) > 0.5: _problems.append("case⑦ 英雄精灵世界落位偏移 pos=%s expect=%s" % [str(bv._world.hero.position), str(expect)]) if _problems.is_empty():