Files
gplan-2/game/smoke/fx_probe.gd
T
DKChan d458e393de feat(art): T3 演出密度终稿批——演出四项落码+fx_probe 新探针
死亡碎裂(standee mark_dead 增五碎块抛物线弹飞 0.45s——§4.6.4 灰化+碎裂禁瞬间消失+§8.4 冻结值);意图三档动画终稿(§4.6.4:档①普通攻击零表示不变/档②特殊准备=弹入+二次弹跳高举/档③重击蓄力=缓推 1.22+定格微顿+回落——三档运动签名互异灰度可辨);胜利纹章(battle_end open_victory 蜡封落定后十碎砖自四周拼纹章环,驻留至 close——§2.4);失败掸灰(open_defeat 八尘絮飘落——§2.5)+既有旗光收回挂探针;结算轮光带终稿(加 2px 亮金前导缘线——§2.2 逐行横扫方向可读)。全部程序化 tween 零新帧资产,确定性散布禁全局随机,时长全走 UiKit.motion 减动效包装。
新探针 smoke/fx_probe.tscn+gd:死亡碎裂5/意图三档+零表示/纹章10/掸灰8+旗光8/光带+缘线 五断言全 PASS。
连带:图例旗条目名回退『旗』(click_probe 图例基线精确匹配;T1 曾改旗(封印印记)——封印语义移描述列,色 #000000 保留)。轻闸=冒烟 557/0+五探针(ui_input/ui_probe/click/tune/fx)全 PASS。
2026-09-28 04:34:51 +08:00

79 lines
3.4 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VERTICAL SLICE - NOT FOR PRODUCTION
# 演出密度探针(样张 v2 冻结批 T3——演出四项可触发+探针断言覆盖):
# ①死亡碎裂(standee mark_dead → 碎块计数)②意图三档动画(damage/buff/debuff/charge 摇定不炸+徽标可见)
# ③胜利纹章+失败掸灰+旗光收回(battle_end open_victory/open_defeat → fx_probe 计数)
# ④结算轮光带(settlement_fx play_round_sweep → 子节点落位)。
# 运行:Godot_console.exe --headless --path . res://smoke/fx_probe.tscn
extends Node
func _ready() -> void:
await get_tree().process_frame
var problems: Array = []
# ---- ①② 站桩侧:死亡碎裂 + 意图三档 ----
var sb_script := load("res://presentation/views/standee_body.gd")
var sb = sb_script.new("enemy")
sb.box = Vector2(150, 176) # 站桩盒几何(Node2D 自定义字段——非 Control.size)
add_child(sb)
sb.set_data({"display_name": "地精", "enemy_id": "goblin", "hp": 10, "max_hp": 10})
await get_tree().process_frame
# 意图三档:特殊准备(damage/buff/debuff)与蓄力档(heavy)摇定——动画触发+徽标可见
for tier in [["damage", "slash"], ["buff", "atk_up"], ["debuff", "weaken_hit"], ["damage", "heavy"]]:
sb.set_pending(tier[0], tier[1])
if not sb.intent_probe().visible:
problems.append("意图徽标应可见(%s/%s)" % [tier[0], tier[1]])
await get_tree().process_frame
sb.set_pending("basic", "") # 档①普通攻击=零表示
if sb.intent_probe().visible:
problems.append("普通攻击徽标应零表示(§4.6.4 档①)")
# 死亡碎裂
sb.mark_dead()
await get_tree().process_frame
var dp: Dictionary = sb.fx_probe()
if int(dp.get("death_shards", 0)) != 5:
problems.append("死亡碎块应 5 块(§8.4 冻结值),实得 %s" % [dp.get("death_shards")])
if not sb.is_dead():
problems.append("mark_dead 后 is_dead 应真")
# ---- ③ 终局侧:胜利纹章 / 失败掸灰+旗光 ----
var end_ov := BattleEndOverlay.new()
add_child(end_ov)
var br := Rect2(300, 300, 400, 300)
end_ov.open_victory("胜利", "继续", br)
await get_tree().process_frame
var vp: Dictionary = end_ov.fx_probe()
if int(vp.get("crest_shards", 0)) != 10:
problems.append("胜利纹章碎砖应 10 枚(§2.4),实得 %s" % [vp.get("crest_shards")])
end_ov.close()
end_ov.open_defeat("失败", "重来", br)
await get_tree().process_frame
var fp: Dictionary = end_ov.fx_probe()
if int(fp.get("dust_motes", 0)) != 8:
problems.append("失败掸灰尘絮应 8 枚(§2.5),实得 %s" % [fp.get("dust_motes")])
if int(fp.get("flag_dots", 0)) != 8:
problems.append("旗光收回应 8 点,实得 %s" % [fp.get("flag_dots")])
end_ov.close()
# ---- ④ 结算轮光带(含前导亮缘) ----
var sfx := SettlementFxView.new()
add_child(sfx)
sfx.play_round_sweep(br) # 光带几何全由 board_rect 驱动——无需容器尺寸
await get_tree().process_frame
var n_fx := 0
for ch in sfx.get_children():
if ch is ColorRect:
n_fx += 1
if n_fx < 2:
problems.append("结算光带应含带体+前导缘线 ≥2 节点,实得 %d" % n_fx)
# ---- 汇总 ----
if problems.is_empty():
print("[fx_probe] PASS — 死亡碎裂5块/意图三档+零表示/胜利纹章10/失败掸灰8+旗光8/结算光带+缘线 全链路通过")
get_tree().quit(0)
else:
for p in problems:
print("[fx_probe] FAIL — " + p)
print("[fx_probe] FAIL — %d 项断言未过" % problems.size())
get_tree().quit(1)