iter8-T6 卡⑦ 轮间结算节奏化:演出层排播队列(_on_step_row 入队+_process 泵+段间 0.3s/段内 0.06s 阶梯——核心层零 await 契约零触碰,step_row 消费体原样搬入 _consume_row 排播后逐位一致)+轮切换「第 N 轮」横幅(settlement_fx_view.play_round_banner 驻留 0.6s 淡入消隐——白名单内取值)+轮首分隔行随队排队(带序正确)+减动效双态(开=同帧直落快路+横幅静态化 create_timer 即隐——行呈现不跳过)+flush-on-modal(任何覆盖层开启前排空队列=明细回看/停点面明细恒完整)+fx_probe 轮横幅双态断言④b——闸:冒烟 593/0+fx/click/input 全绿(click 主循环全程排播态实跑)——MC 零扰动=结构性(纯呈现层,逻辑信号消费零改)T10 复拍。时间盒评估(T6 收口切点):T0-T6 单会话落籍远快于估时,T7-T9 余量充足,不触发切迭代
This commit is contained in:
1 parent
3f46edbfa3
commit
b8e6b27538
3 files changed
+122
-3
No files matched your search
@@ -87,6 +87,16 @@ var _refresh_used_round := 0 # 本轮已受理刷新次数(遥测 round_r
|
||||
var _boss_active := false # Boss 遭遇变体(阶段指示附 Boss 名)
|
||||
var _was_settling := false # 结算相位上升沿检测(结算轮光带触发——演出链批)
|
||||
|
||||
# ---- 结算行排播队列(迭代 8 卡⑦——演出层排播:逻辑先行零回压,行按段分组阶梯延迟进明细带)----
|
||||
# 硬契约:核心层零 await 不破——本队列只做信号的"后置消费",结算顺序/结果/时序逻辑零改动(§3 契约 1);
|
||||
# 减动效开=延迟归零走同帧直落快路(行呈现不跳过——§3 契约 5);模态开启前强制排空(明细回看/停点
|
||||
# 覆盖层所见明细带恒完整)。
|
||||
var _row_queue: Array = [] # 待排播行(step_row 载荷原样入队;__round_line 标记=轮首分隔行)
|
||||
var _row_pace_wait := 0.0 # 距下一行排播的剩余秒(_process 消耗)
|
||||
var _pace_prev_segment := "" # 上一排播行的段型(段间/段内延迟判据)
|
||||
const PACE_SEGMENT_GAP := 0.3 # 段间阶梯延迟(代拍板:白名单 0.2–0.4s 内取值,追认清单呈报)
|
||||
const PACE_ROW_GAP := 0.06 # 段内快排间隔(同行段连读性——非白名单约束面)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
db = get_node("/root/ConfigDB")
|
||||
@@ -224,6 +234,7 @@ func _register_modal(m: Control) -> void:
|
||||
|
||||
func _open_modal(m: Control) -> void:
|
||||
# 打开时显式隐藏树序在其上方的可见层(遮挡物隐藏),关闭恢复——单一模态栈
|
||||
_flush_row_queue() # 卡⑦——任何覆盖层开启前排空排播队列(明细带恒完整,回看/停点面不缺行)
|
||||
_modals.open(m)
|
||||
|
||||
|
||||
@@ -600,6 +611,19 @@ func _wire_battle(settlement_ref) -> void:
|
||||
|
||||
|
||||
func _on_step_row(row: Dictionary) -> void:
|
||||
# 卡⑦ 排播入口:减动效=延迟归零同帧直落(行呈现不跳过);常态入队按段阶梯播放
|
||||
if UiKit.motion_scale < 1.0:
|
||||
_consume_row(row)
|
||||
return
|
||||
_row_queue.append(row)
|
||||
|
||||
|
||||
# 行消费(排播队列的出队步 / 减动效快路共用):明细带入带+演出链+呈现刷新——与卡⑦前排位逐位一致
|
||||
func _consume_row(row: Dictionary) -> void:
|
||||
if row.has("__round_line"):
|
||||
log_view.finish_settlement_round() # 上轮摘要行(明细带 pattern 3)随轮首分隔行落带
|
||||
log_view.append_bb("[color=#e0b860]── 第 %d 轮 ──[/color]" % int(row["__round_line"]))
|
||||
return
|
||||
log_view.append_row(row)
|
||||
stage.on_step_row_fx(row)
|
||||
_play_cross_zone_fx(row) # 跨区因果演出(结算演出链批):开格之因 → 站桩之果
|
||||
@@ -611,6 +635,37 @@ func _on_step_row(row: Dictionary) -> void:
|
||||
_refresh_presentations()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
# 排播泵(卡⑦——演出层帧驱动;队列空=零开销直返)
|
||||
if _row_queue.is_empty():
|
||||
_row_pace_wait = 0.0
|
||||
_pace_prev_segment = ""
|
||||
return
|
||||
_row_pace_wait -= delta
|
||||
if _row_pace_wait > 0.0:
|
||||
return
|
||||
var entry: Dictionary = _row_queue.pop_front()
|
||||
_consume_row(entry)
|
||||
var seg := String(entry.get("type", ""))
|
||||
_row_pace_wait = 0.0 if UiKit.motion_scale < 1.0 else (PACE_SEGMENT_GAP if seg != _pace_prev_segment else PACE_ROW_GAP)
|
||||
_pace_prev_segment = seg
|
||||
|
||||
|
||||
# 段间延迟取数面(减动效双态断言用——开=0 归零,行不跳过;常态=段间/段内两档)
|
||||
func pace_delay_for(prev_seg: String, next_seg: String) -> float:
|
||||
if UiKit.motion_scale < 1.0:
|
||||
return 0.0
|
||||
return PACE_SEGMENT_GAP if prev_seg != next_seg else PACE_ROW_GAP
|
||||
|
||||
|
||||
# 强制排空(模态开启前调用——明细回看/停点覆盖层/终局面所见明细带恒完整)
|
||||
func _flush_row_queue() -> void:
|
||||
while not _row_queue.is_empty():
|
||||
_consume_row(_row_queue.pop_front())
|
||||
_row_pace_wait = 0.0
|
||||
_pace_prev_segment = ""
|
||||
|
||||
|
||||
# 跨区因果演出(§Transitions 结算逐行兑现——动画密度终稿归战斗表现样张批):
|
||||
# 伤害行 → ⚔ 弹道自棋盘飞向目标敌方站桩(crit 金档加重);治疗行 → ✚ 弹道飞向主角站桩;
|
||||
# 命中反馈(闪白/血条递减/灰化)由站桩侧 on_step_row_fx/set_data 承接
|
||||
@@ -637,8 +692,14 @@ func _play_cross_zone_fx(row: Dictionary) -> void:
|
||||
|
||||
|
||||
func _on_round_started(ri: int) -> void:
|
||||
log_view.finish_settlement_round() # 上轮摘要行(挖掘期 1 行——明细带 pattern 3)
|
||||
log_view.append_bb("[color=#e0b860]── 第 %d 轮 ──[/color]" % ri)
|
||||
# 卡⑦:轮首分隔行随排播队列走(落在前轮各行之后——带序正确);轮横幅即轮切换时刻发射
|
||||
#(view 内判减动效=静态化变体)。减动效快路=分隔行同帧直落(不跳过)。
|
||||
if UiKit.motion_scale < 1.0:
|
||||
log_view.finish_settlement_round()
|
||||
log_view.append_bb("[color=#e0b860]── 第 %d 轮 ──[/color]" % ri)
|
||||
else:
|
||||
_row_queue.append({"__round_line": ri})
|
||||
settlement_fx.play_round_banner(ri)
|
||||
_refresh_used_round = 0
|
||||
_refresh_presentations()
|
||||
|
||||
|
||||
@@ -65,3 +65,42 @@ func play_projectile(from: Vector2, to: Vector2, glyph: String, col: Color, crit
|
||||
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)
|
||||
|
||||
|
||||
# ---- 轮切换横幅(迭代 8 卡⑦——「第 N 轮」驻留 0.6s 后消隐进下一轮;白名单 0.5–0.8s 内取值)----
|
||||
# 减动效=静态呈现(驻留后即隐,零位移/零透明度动画——行呈现不跳过同语义,卡⑦ AC③)。
|
||||
const BANNER_DWELL := 0.6
|
||||
|
||||
var _fx_banners := 0 # 演出探针计数(fx_probe 断言面)
|
||||
|
||||
|
||||
# 演出探针出口(卡⑦——轮横幅发射计数)
|
||||
func probe_banners() -> int:
|
||||
return _fx_banners
|
||||
|
||||
|
||||
func play_round_banner(ri: int) -> void:
|
||||
_fx_banners += 1
|
||||
var banner := Panel.new()
|
||||
banner.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
banner.add_theme_stylebox_override("panel", UiKit.panel_flat(Color(UiKit.BG_OVERLAY, 0.88), UiKit.GOLD_DEEP, 8, 2))
|
||||
var lab := UiKit.label("第 %d 轮" % ri, 22, true)
|
||||
lab.add_theme_color_override("font_color", UiKit.GOLD)
|
||||
lab.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
lab.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
lab.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
banner.add_child(lab)
|
||||
banner.size = Vector2(190, 46)
|
||||
banner.position = Vector2((size.x - banner.size.x) * 0.5, size.y * 0.30) # 棋盘中带上缘——不压明细带
|
||||
banner.z_index = 4
|
||||
add_child(banner)
|
||||
if UiKit.motion_scale < 1.0:
|
||||
var st := get_tree().create_timer(BANNER_DWELL)
|
||||
st.timeout.connect(banner.queue_free)
|
||||
return
|
||||
banner.modulate.a = 0.0
|
||||
var tw := banner.create_tween()
|
||||
tw.tween_property(banner, "modulate:a", 1.0, UiKit.motion(0.15))
|
||||
tw.tween_interval(UiKit.motion(BANNER_DWELL))
|
||||
tw.tween_property(banner, "modulate:a", 0.0, UiKit.motion(0.25))
|
||||
tw.tween_callback(banner.queue_free)
|
||||
+20
-1
@@ -77,6 +77,25 @@ func _ready() -> void:
|
||||
if n_fx < 2:
|
||||
problems.append("结算光带应含带体+前导缘线 ≥2 节点,实得 %d" % n_fx)
|
||||
|
||||
# ---- ④b 轮切换横幅双态(迭代 8 卡⑦——常态=淡入驻留消隐动画链;减动效=静态呈现零动画)----
|
||||
sfx.play_round_banner(3)
|
||||
await get_tree().process_frame
|
||||
var banner_nodes := 0
|
||||
for ch in sfx.get_children():
|
||||
if ch is Panel:
|
||||
banner_nodes += 1
|
||||
if banner_nodes != 1:
|
||||
problems.append("轮横幅应落位 1 面(卡⑦),实得 %d" % banner_nodes)
|
||||
if int(sfx.probe_banners()) != 1:
|
||||
problems.append("轮横幅计数失守(probe_banners=%s)" % sfx.probe_banners())
|
||||
var saved_motion: float = UiKit.motion_scale
|
||||
UiKit.motion_scale = 0.5
|
||||
sfx.play_round_banner(4)
|
||||
await get_tree().process_frame
|
||||
if int(sfx.probe_banners()) != 2:
|
||||
problems.append("减动效轮横幅未发射(卡⑦ AC③——静态化仍呈现不跳过)")
|
||||
UiKit.motion_scale = saved_motion
|
||||
|
||||
# ---- ⑤ 主角三态切换(迭代 6 T3——attack/hit 短驻自回 + 死亡复活态回 idle) ----
|
||||
var hero_sb = sb_script.new("hero")
|
||||
hero_sb.box = Vector2(150, 176)
|
||||
@@ -129,7 +148,7 @@ func _ready() -> void:
|
||||
|
||||
# ---- 汇总 ----
|
||||
if problems.is_empty():
|
||||
print("[fx_probe] PASS — 死亡碎裂5块/命中火花6/意图三档+零表示/胜利纹章10/失败掸灰8+旗光8/结算光带+缘线/主角三态切换 全链路通过")
|
||||
print("[fx_probe] PASS — 死亡碎裂5块/命中火花6/意图三档+零表示/胜利纹章10/失败掸灰8+旗光8/结算光带+缘线/轮横幅双态/主角三态切换 全链路通过")
|
||||
get_tree().quit(0)
|
||||
else:
|
||||
for p in problems:
|
||||
|
||||
Reference in new issue
Block a user