P10.3: wire the SFX bank to game events (sx / iOS)
Drive event-appropriate cues from the existing System Sound Services bank, purely additively — no board/score/move state is read or written and every call stays inline-if-OS==.ios guarded. board_view.sx (move-commit path): a committed gesture now plays the swap slide cue for any swipe intent (legal or the reverted ping-back); a legal move adds the match pop on its first clearing round; a multi-round chain adds the escalating cascade cue keyed to the recorded AnimMove depth (mv.rounds.len), kept distinct from the match pop so a single clear is never doubled. An illegal swap plays only the swap cue. main.sx (frame loop): the win/lose stinger fires EXACTLY ONCE, edge-triggered on the frame the banner comes up — the level has settled won/lost and any in-flight cascade has finished animating. Status is read-only from the model; a restart re-arms the edge for a fresh win/lose. audio.sx: each play_* method logs a per-cue NSLog line at play time so the ordering is observable via `log show`; cascade_cue_name maps the clamped combo index to a stable literal (literals only — the string→NSString bridge needs NUL-terminated bytes).
This commit is contained in:
@@ -642,11 +642,18 @@ impl View for BoardView {
|
||||
mv := plan_and_commit(self.board, intent.a, intent.b);
|
||||
if self.anim != null { self.anim.begin(mv); }
|
||||
if self.fx != null { self.fx.begin(@mv); }
|
||||
// SFX (P10.2). Additive only — plays the ascending cascade
|
||||
// cue (combo1..combo5, clamped by depth) when a swap actually
|
||||
// clears a match; reads no score/board state and writes none.
|
||||
// A legal move has >=1 cascade round.
|
||||
if mv.legal and mv.rounds.len > 0 { sfx_cascade(mv.rounds.len); }
|
||||
// SFX (P10.3): additive cues for the committed gesture —
|
||||
// never reads or writes board/score/move state. The swap
|
||||
// slide cue plays for any committed gesture (legal or the
|
||||
// reverted ping-back); a legal move adds the match pop on its
|
||||
// first clearing round; a multi-round chain adds the escalating
|
||||
// cascade cue keyed to recorded depth (mv.rounds.len), distinct
|
||||
// from the match pop so a single clear is never doubled.
|
||||
sfx_swap();
|
||||
if mv.legal {
|
||||
sfx_match();
|
||||
if mv.rounds.len >= 2 { sfx_cascade(mv.rounds.len); }
|
||||
}
|
||||
self.sel.clear();
|
||||
} else {
|
||||
if hit := self.layout.point_to_cell(start) {
|
||||
|
||||
Reference in New Issue
Block a user