P18.2: organic combine — staggered clear ripple (sx, iOS sim)
Within a clearing round the matched gems no longer all explode at once: each gem's pop (and its burst) START is offset by a bounded per-gem delay so the cells detonate as a ripple. - board_anim.sx: clear_ripple_t(t,u) mirrors fall_stagger_t's (t-delay)/window, delaying a gem's pop START by CLEAR_STAGGER_MAX*u (0.45 of the clear window). Bounded: every gem still reaches local 1 (scale 0) by t==1, so none is left mid-pop at the seam to the fall. clear_diag_span/clear_rank rank each matched gem 0..1 by diagonal (col+row) PER ROUND, so even a 3-match ripples across the full budget. - board_view.sx render_clear: feed each matched gem's ranked, staggered local t through the P18.1 clear_pop_scale (locked endpoints unchanged). - board_fx.sx: bursts carry the same per-gem delay so they ripple in lockstep with the pops. Per-round audio cue (P10.10) still fires once at t0, not per gem. - Model untouched (same cells cleared, same final board); CLEAR_ANIM_DUR fixed, so cascade-cue snapshots don't churn and M3TE_ANIM_TIME=0 still rests. - tests/easing.sx: pin clear_ripple_t endpoints, bounded completion by t==1, monotonicity, ripple ordering, and the diagonal rank. - goldens: add p18_stagger (M3TE_FX=3 @ 0.22); refresh p18_pop, p6_fx_match, p11_combo_deep (all pinned mid-clear, now showing the ripple).
This commit is contained in:
13
board_fx.sx
13
board_fx.sx
@@ -223,15 +223,22 @@ BoardFx :: struct {
|
||||
rd := @mv.rounds.items[k];
|
||||
t0 := SWAP_ANIM_DUR + cast(f32) k * (CLEAR_ANIM_DUR + FALL_ANIM_DUR);
|
||||
extra := depth_boost + FX_BURST_COMBO * cast(f32) min(k, 2);
|
||||
// Stagger each burst's START by its gem's clear-ripple rank so the
|
||||
// bursts ripple in lockstep with the staggered pops (P18.2) instead of
|
||||
// one simultaneous flash. The round's audio cue still fires once at t0.
|
||||
span := clear_diag_span(@rd.matched);
|
||||
for 0..BOARD_CELLS: (idx) {
|
||||
if rd.matched.cells[idx] {
|
||||
g := rd.before[idx];
|
||||
if g != .empty {
|
||||
col := idx % BOARD_COLS;
|
||||
row := idx / BOARD_COLS;
|
||||
rdelay := CLEAR_STAGGER_MAX * clear_rank(span, col, row) * CLEAR_ANIM_DUR;
|
||||
self.particles.append(FxParticle.{
|
||||
col = cast(f32) (idx % BOARD_COLS) + 0.5,
|
||||
row = cast(f32) (idx / BOARD_COLS) + 0.5,
|
||||
col = cast(f32) col + 0.5,
|
||||
row = cast(f32) row + 0.5,
|
||||
tint = cast(s64) g,
|
||||
delay = t0,
|
||||
delay = t0 + rdelay,
|
||||
age = 0.0,
|
||||
life = FX_BURST_LIFE,
|
||||
peak = FX_BURST_BASE + extra,
|
||||
|
||||
Reference in New Issue
Block a user