merge: 英雄精灵世界落位缺陷修复+B区立绘换装(2026-09-26)

This commit is contained in:
DKChan committed 2026-09-25 06:09:21 +08:00
commit ce9c2c15d7
5 files changed
+32 -12

No files matched your search

+1 -1
View File
@@ -35,7 +35,7 @@ func _init(db_ref) -> void:
vb.add_child(row)
hero_standee = StandeeView.new("hero")
hero_standee.set_portrait_texture(UiKit.load_tex(UiKit.TEX_HERO_IDLE)) # 棋盘小人贴图批 2026-09-25(挂点现成——null 回退字形「人」;NEAREST 归 set_portrait_texture 单点)
hero_standee.set_portrait_texture(UiKit.load_tex(UiKit.TEX_HERO_PORTRAIT), true) # B 区立绘 48×48 朝右(2026-09-26 用户点名 hero_idle_01 换装+水平向右;素材缺位 null 回退字形「人」)
row.add_child(hero_standee)
var center := CenterContainer.new()
+7 -5
View File
@@ -339,16 +339,18 @@ func cell_origin(c: Vector2i) -> Vector2:
return _svp_container.position + Vector2(c) * (_cell + float(SEP))
# 英雄 32×32 盒格内居中的脚底锚点(盒底中点——弹跳 scale.y 向此收敛)
# 英雄 32×32 盒格内居中的脚底锚点——**世界坐标**(精灵在 SubViewport 世界内:格原点 = 格×步距,
# 禁带壳层居中偏移。2026-09-26 修正:上批误用壳层 cell_origin(含 _svp_container.position 居中
# 偏移)定位世界内精灵,实测整体右偏 ~7 格+偏离格心——实机截图用户报缺陷)
func _hero_feet(c: Vector2i) -> Vector2:
var m := (_cell - HERO_FRAME_PX) * 0.5
return cell_origin(c) + Vector2(m + HERO_FRAME_PX * 0.5, m + HERO_FRAME_PX)
return Vector2(c) * (_cell + float(SEP)) + Vector2(m + HERO_FRAME_PX * 0.5, m + HERO_FRAME_PX)
# 英雄持握手位(fx 同层坐标系)——挥铲特效圆心(2026-09-25 用户裁决:以手为圆心、铲长为半径
# 旋转;手 = 盒底往上 1/4 盒高、水平居中)
# 英雄持握手位(fx 同层坐标系 = 壳层坐标——fx 在 SubViewport 之外,须含 _svp_container.position
# 居中偏移:世界脚底锚 + 壳层偏移即得)。手 = 盒底往上 1/4 盒高、水平居中(2026-09-25 用户裁决)
func hero_hand_point() -> Vector2:
return _hero_feet(_hero_last) + Vector2(0.0, -HERO_FRAME_PX * 0.25)
return _svp_container.position + _hero_feet(_hero_last) + Vector2(0.0, -HERO_FRAME_PX * 0.25)
# 英雄精灵缩放档(fx 挥铲同档出口——两演出比例恒一致)
+8 -4
View File
@@ -224,19 +224,23 @@ func _play_intent_motion() -> void:
tw.tween_property(_portrait, "rotation_degrees", 0.0, UiKit.motion(0.14))
# 资产挂点(战斗表现样张批):tex 落位后字形隐退、纹理立绘顶位——零代码换装契约;tex=null 回退字形
func set_portrait_texture(tex: Texture2D) -> void:
# 资产挂点(战斗表现样张批):tex 落位后字形隐退、纹理立绘顶位——零代码换装契约;tex=null 回退字形。
# flip = 立绘朝向翻转(素材基准朝左时传 true 呈现朝右——2026-09-26 用户点名英雄立绘水平向右)。
# 盒高 96px = 48px 立绘源整数 2×(圣经 §8.2 禁非整数缩放;offset_top 44 = 血条+状态行之下净空)——
# 源换代时随源重算盒高。
func set_portrait_texture(tex: Texture2D, flip: bool = false) -> void:
if _portrait_tex == null:
_portrait_tex = TextureRect.new()
_portrait_tex.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
_portrait_tex.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
_portrait_tex.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST # 32px 像素帧放大防糊(棋盘小人贴图批 2026-09-25)
_portrait_tex.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST # 像素帧放大防糊(棋盘小人贴图批 2026-09-25)
_portrait_tex.set_anchors_preset(Control.PRESET_FULL_RECT)
_portrait_tex.offset_top = 44.0
_portrait_tex.offset_bottom = -26.0
_portrait_tex.offset_bottom = -36.0 # 盒高 96 = 48 源 ×2 整数档(原 −26 盒高 106 系非整数缩放)
_portrait_tex.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(_portrait_tex)
_portrait_tex.texture = tex
_portrait_tex.flip_h = flip
_portrait_tex.visible = tex != null
_portrait.visible = tex == null
+1
View File
@@ -79,6 +79,7 @@ static func motion(dur: float) -> float:
# 的字形/无演出回退路径;禁 preload(素材缺位树上直接断言炸脚本,冒烟安全红线)
const TEX_HERO_IDLE := "res://assets/art/character/character_hero_idle.png"
const TEX_HERO_WALK := "res://assets/art/character/character_hero_walk.png"
const TEX_HERO_PORTRAIT := "res://assets/art/character/character_hero_portrait.png" # B 区站桩立绘 48×48(源档 candidates/hero-idle/hero_idle_01.png,2026-09-26 用户点名换装)
# 素材纹理守卫装载(exists 检查避开缺位树上 ResourceLoader 报错刷屏——冒烟/无素材检出静默回退)
+15 -2
View File
@@ -4,7 +4,8 @@
# 本探针是真实输入路径的唯一自动化覆盖:鼠标事件 → 壳层 _gui_input → 板级公式换算(_cell_at)→
# 悬停/点选/chord 既有出口 → 组合根信号。四 case:①悬停可挖域(金框+十字光标)②悬停禁入
# (hover_forbidden 信号+灰禁红框)③悬停已开格(路径预览点迹+移动光标)④右键插旗(flag_place
# 到达组合根+核心旗态)⑤双击 chord(禁入格双左击,核心拒挖零副作用)⑥左键挖(dig 到达组合根+核心揭格)。
# 到达组合根+核心旗态)⑤双击 chord(禁入格双左击,核心拒挖零副作用)⑥左键挖(dig 到达组合根+核心揭格)
# ⑦英雄精灵世界落位(棋盘小人贴图批回归闸——SubViewport 世界坐标判据,素材缺位树跳过)。
# 事件路径:Viewport.push_input(ev, in_local_coords=true)——落点用 BoardView.cell_center_local
# (与 _cell_at 同一公式族)换算画布坐标,SubViewportContainer mouse_filter=IGNORE 不拦截。
# 运行:Godot_console.exe --headless --path . res://smoke/ui_input_probe.tscn
@@ -120,8 +121,20 @@ func _ready() -> void:
await get_tree().process_frame
if not ms.is_revealed(dig_t):
_problems.append("case⑥ 核心揭格未落位(目标=%s)" % dig_t)
# ---- case⑦ 英雄精灵世界落位(棋盘小人贴图批回归闸 2026-09-26):精灵在 SubViewport 世界内,
# 落位 = 格×步距 + 居中脚底锚(禁带壳层 _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 hm: float = (bv.cell_size - bv.HERO_FRAME_PX) * 0.5
var expect: Vector2 = Vector2(ms.hero_pos()) * (bv.cell_size + float(bv.SEP)) \
+ Vector2(hm + bv.HERO_FRAME_PX * 0.5, hm + bv.HERO_FRAME_PX)
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():
print("[ui_input_probe] PASS — 悬停金框/禁入信号/路径预览/flag_place/chord/dig 六断言全绿(真实 push_input 路径)")
print("[ui_input_probe] PASS — 悬停金框/禁入信号/路径预览/flag_place/chord/dig/英雄落位 七断言全绿(真实 push_input 路径)")
get_tree().quit(0)
else:
for p in _problems: