P11.2: escalating combo emphasis tied to cascade depth (sx / iOS)
Scale the combo FX with cascade depth (mv.rounds.len) — the same depth the cascade SFX (play_cascade) steps up on — so deeper cascades read as more exciting and land in lockstep with the audio escalation. Purely visual and self-pruning: no board / score / move state changes, and input stays gated by BoardAnim.active alone. - board_fx.sx: add fx_combo_level (mirrors audio's cascade_cue_index clamp: depth<=1 -> floor, depth>=5 -> ceiling). The +points popup now carries the cascade depth and grows one font step + lerps gold -> hot-gold per level (fx_popup_font / fx_popup_color). Every burst of a deep cascade gets a whole-move depth boost (FX_BURST_DEPTH) on top of the existing per-round bump. - board_view.sx: render_fx_popups derives styling from depth and tops a combo with a "COMBO xN" label naming the true cascade depth. - tests/fx_combo.sx: headless snapshot locking the depth->level/font table and asserting fx_combo_level matches the cascade-cue index column entry-for-entry. - goldens/p11_combo_deep.png + README: deterministic depth-5 capture (M3TE_FX=11) vs the depth-1 single clear (M3TE_FX=3); FX gone after settle at a later phase.
This commit is contained in:
@@ -428,6 +428,9 @@ BoardView :: struct {
|
||||
// Floating "+points" popups: rise and fade above the initial clear. Drawn
|
||||
// unclipped (over everything) so the number stays legible as it lifts off
|
||||
// the grid. The text path honours the colour's alpha, so these truly fade.
|
||||
// A combo (depth > 1) escalates with cascade depth: gold and larger, topped
|
||||
// by a `COMBO xN` label naming the depth — the same depth the cascade SFX
|
||||
// escalates on — so deeper cascades read as more exciting.
|
||||
render_fx_popups :: (self: *BoardView, ctx: *RenderContext) {
|
||||
if self.fx == null or self.fx.popups.len == 0 { return; }
|
||||
cs := self.layout.cell_size;
|
||||
@@ -436,8 +439,8 @@ BoardView :: struct {
|
||||
lt := (q.age - q.delay) / q.life;
|
||||
if lt >= 0.0 {
|
||||
fade := fx_popup_fade(lt);
|
||||
font := if q.combo then FX_POPUP_COMBO_FONT else FX_POPUP_FONT;
|
||||
base := if q.combo then FX_POPUP_COMBO_COLOR else FX_POPUP_COLOR;
|
||||
font := fx_popup_font(q.depth);
|
||||
base := fx_popup_color(q.depth);
|
||||
col := Color.{ r = base.r, g = base.g, b = base.b, a = cast(u8) (fade * 255.0) };
|
||||
txt := format("+{}", q.points);
|
||||
sz := measure_text(txt, font);
|
||||
@@ -447,6 +450,16 @@ BoardView :: struct {
|
||||
Frame.make(cx - sz.width * 0.5, cy - sz.height * 0.5, sz.width, sz.height),
|
||||
txt, font, col
|
||||
);
|
||||
if q.depth > 1 {
|
||||
lfont := font * FX_COMBO_LABEL_RATIO;
|
||||
ltxt := format("COMBO x{}", q.depth);
|
||||
lsz := measure_text(ltxt, lfont);
|
||||
lcy := cy - sz.height * 0.5 - cs * FX_COMBO_LABEL_GAP - lsz.height * 0.5;
|
||||
ctx.add_text(
|
||||
Frame.make(cx - lsz.width * 0.5, lcy - lsz.height * 0.5, lsz.width, lsz.height),
|
||||
ltxt, lfont, col
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user