死亡碎裂(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。
68 lines
3.8 KiB
GDScript
68 lines
3.8 KiB
GDScript
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||
# 实现 GDD:design/ux/battle.md(§Transitions 结算逐行兑现——B 区因果演出链骨架:
|
||
# 结算轮光带自棋盘区横扫 → 伤害/治疗弹道自棋盘飞向敌我站桩 → 受击闪白与血条递减由站桩侧承接)。
|
||
# 位置语义:全屏覆盖层(A–D 区之上、模态之下),只做跨区飞行的演出载体——棋盘区内演出
|
||
# (清图金粒/完美排雷横幅/标中旗弹道/Boss 影子)仍归 board_fx_view。
|
||
# 高内聚边界:纯演出——组合根按结算信号调用 play_*,传全局坐标(组合根持有棋盘与站桩两域句柄);
|
||
# 本类零核心依赖、不自持游戏状态、mouse_filter 全忽略(不劫持输入)。
|
||
# 动画密度/缓动曲线归战斗表现样张批终稿——本批落"因果全程可见"骨架(规划兑现 P2 义务)。
|
||
# Date: 2026-09-20(结算演出链批)
|
||
class_name SettlementFxView
|
||
extends Control
|
||
|
||
|
||
func _init() -> void:
|
||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
set_anchors_preset(Control.PRESET_FULL_RECT)
|
||
|
||
|
||
# 结算轮光带:金橙半透明横带自棋盘上缘扫至下缘(一次 0.5s,自动回收)——
|
||
# "棋盘能量向战斗画面汇聚"的开轮语义(§2.2 色彩转金橙主导;区分于 board_fx 的完美排雷金光带)。
|
||
# 终稿(样张 v2 冻结批 T3):加 2px 亮金前导缘线——扫带运动方向可读(兑现光带逐行横扫 §2.2)
|
||
func play_round_sweep(board_rect: Rect2) -> void:
|
||
if board_rect.size == Vector2.ZERO:
|
||
return
|
||
var band := ColorRect.new()
|
||
band.color = Color(UiKit.GOLD, 0.22)
|
||
band.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
band.position = Vector2(board_rect.position.x, board_rect.position.y)
|
||
band.size = Vector2(board_rect.size.x, 34.0)
|
||
add_child(band)
|
||
var edge := ColorRect.new()
|
||
edge.color = Color(UiKit.GOLD_LIT, 0.7)
|
||
edge.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
edge.size = Vector2(board_rect.size.x, 2.0)
|
||
edge.position = band.position
|
||
add_child(edge)
|
||
var tw := band.create_tween()
|
||
tw.tween_property(band, "position:y", board_rect.end.y - 34.0, UiKit.motion(0.5)).set_trans(Tween.TRANS_SINE)
|
||
tw.parallel().tween_property(band, "modulate:a", 0.0, UiKit.motion(0.5)).set_delay(UiKit.motion(0.15))
|
||
tw.tween_callback(band.queue_free)
|
||
var etw := edge.create_tween()
|
||
etw.tween_property(edge, "position:y", board_rect.end.y - 2.0, UiKit.motion(0.5)).set_trans(Tween.TRANS_SINE)
|
||
etw.parallel().tween_property(edge, "modulate:a", 0.0, UiKit.motion(0.2)).set_delay(UiKit.motion(0.3))
|
||
etw.tween_callback(edge.queue_free)
|
||
|
||
|
||
# 跨区弹道:glyph 字形自 from 飞向 to(0.35s + 轻微上抛弧线 + 终点淡出,自动回收)——
|
||
# 开格之因 → 站桩之果的因果可视承载(P2);crit 弹道由调用方传加重标记
|
||
func play_projectile(from: Vector2, to: Vector2, glyph: String, col: Color, crit: bool = false) -> void:
|
||
var shot := UiKit.label(glyph, 22 if crit else 16, true)
|
||
shot.add_theme_color_override("font_color", col)
|
||
shot.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
shot.size = Vector2(24, 24)
|
||
shot.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||
shot.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||
shot.position = from - shot.size * 0.5
|
||
shot.pivot_offset = shot.size * 0.5
|
||
shot.z_index = 5
|
||
add_child(shot)
|
||
var mid := (from + to) * 0.5 + Vector2(0, -36.0) # 轻微上抛弧线
|
||
var tw := shot.create_tween()
|
||
if crit:
|
||
tw.tween_property(shot, "scale", Vector2(1.5, 1.5), UiKit.motion(0.08))
|
||
tw.tween_property(shot, "position", mid, UiKit.motion(0.16)).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_OUT)
|
||
tw.tween_property(shot, "position", to - shot.size * 0.5, UiKit.motion(0.19)).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN)
|
||
tw.parallel().tween_property(shot, "modulate:a", 0.0, UiKit.motion(0.12)).set_delay(UiKit.motion(0.23))
|
||
tw.tween_callback(shot.queue_free)
|