fix(sound): add pre game die roll & opponent points sounds
This commit is contained in:
parent
9bdb32b364
commit
60d8e0326a
3 changed files with 62 additions and 24 deletions
|
|
@ -152,13 +152,24 @@ pub fn GameScreen(state: GameUiState) -> impl IntoView {
|
||||||
|
|
||||||
// Values for MergedScorePanel — extracted before events are consumed.
|
// Values for MergedScorePanel — extracted before events are consumed.
|
||||||
// Don't animate points when a hole was gained (points wrap around 12).
|
// Don't animate points when a hole was gained (points wrap around 12).
|
||||||
let my_pts_earned: u8 = my_scored_event.as_ref()
|
let my_pts_earned: u8 = my_scored_event.as_ref().map_or(0, |e| {
|
||||||
.map_or(0, |e| if e.holes_gained == 0 { e.points_earned } else { 0 });
|
if e.holes_gained == 0 {
|
||||||
let opp_pts_earned: u8 = opp_scored_event.as_ref()
|
e.points_earned
|
||||||
.map_or(0, |e| if e.holes_gained == 0 { e.points_earned } else { 0 });
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let opp_pts_earned: u8 = opp_scored_event.as_ref().map_or(0, |e| {
|
||||||
|
if e.holes_gained == 0 {
|
||||||
|
e.points_earned
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
});
|
||||||
let my_holes_gained_score: u8 = my_scored_event.as_ref().map_or(0, |e| e.holes_gained);
|
let my_holes_gained_score: u8 = my_scored_event.as_ref().map_or(0, |e| e.holes_gained);
|
||||||
let opp_holes_gained_score: u8 = opp_scored_event.as_ref().map_or(0, |e| e.holes_gained);
|
let opp_holes_gained_score: u8 = opp_scored_event.as_ref().map_or(0, |e| e.holes_gained);
|
||||||
let my_bredouille_flash: bool = my_scored_event.as_ref()
|
let my_bredouille_flash: bool = my_scored_event
|
||||||
|
.as_ref()
|
||||||
.map_or(false, |e| e.bredouille && e.holes_gained > 0);
|
.map_or(false, |e| e.bredouille && e.holes_gained > 0);
|
||||||
|
|
||||||
let is_double_dice = dice.0 == dice.1 && dice.0 != 0;
|
let is_double_dice = dice.0 == dice.1 && dice.0 != 0;
|
||||||
|
|
@ -414,6 +425,10 @@ pub fn GameScreen(state: GameUiState) -> impl IntoView {
|
||||||
guest_die: None,
|
guest_die: None,
|
||||||
tie_count: 0,
|
tie_count: 0,
|
||||||
});
|
});
|
||||||
|
if pgr.host_die != None {
|
||||||
|
crate::game::sound::play_dice_roll();
|
||||||
|
}
|
||||||
|
|
||||||
let my_die = if player_id == 0 { pgr.host_die } else { pgr.guest_die };
|
let my_die = if player_id == 0 { pgr.host_die } else { pgr.guest_die };
|
||||||
let opp_die = if player_id == 0 { pgr.guest_die } else { pgr.host_die };
|
let opp_die = if player_id == 0 { pgr.guest_die } else { pgr.host_die };
|
||||||
let can_roll = my_die.is_none() && !waiting_for_confirm;
|
let can_roll = my_die.is_none() && !waiting_for_confirm;
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
use leptos::prelude::*;
|
|
||||||
use trictrac_store::Jan;
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use gloo_timers::future::TimeoutFuture;
|
use gloo_timers::future::TimeoutFuture;
|
||||||
|
use leptos::prelude::*;
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
use std::sync::{
|
||||||
|
atomic::{AtomicBool, Ordering},
|
||||||
|
Arc,
|
||||||
|
};
|
||||||
|
use trictrac_store::Jan;
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use wasm_bindgen_futures::spawn_local;
|
use wasm_bindgen_futures::spawn_local;
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
|
|
||||||
|
|
||||||
use crate::i18n::*;
|
|
||||||
use crate::game::trictrac::types::PlayerScore;
|
use crate::game::trictrac::types::PlayerScore;
|
||||||
|
use crate::i18n::*;
|
||||||
|
|
||||||
pub fn jan_label(jan: &Jan) -> String {
|
pub fn jan_label(jan: &Jan) -> String {
|
||||||
let i18n = use_i18n();
|
let i18n = use_i18n();
|
||||||
|
|
@ -42,13 +45,16 @@ pub fn MergedScorePanel(
|
||||||
opp_score: PlayerScore,
|
opp_score: PlayerScore,
|
||||||
/// Points just earned this turn; 0 = no animation. Set to 0 when a hole
|
/// Points just earned this turn; 0 = no animation. Set to 0 when a hole
|
||||||
/// was gained (points wrap around 12, counter stays at end value).
|
/// was gained (points wrap around 12, counter stays at end value).
|
||||||
#[prop(default = 0)] my_points_earned: u8,
|
#[prop(default = 0)]
|
||||||
|
my_points_earned: u8,
|
||||||
#[prop(default = 0)] opp_points_earned: u8,
|
#[prop(default = 0)] opp_points_earned: u8,
|
||||||
/// Non-zero when a new hole was just scored (triggers peg-pop animation).
|
/// Non-zero when a new hole was just scored (triggers peg-pop animation).
|
||||||
#[prop(default = 0)] my_holes_gained: u8,
|
#[prop(default = 0)]
|
||||||
|
my_holes_gained: u8,
|
||||||
#[prop(default = 0)] opp_holes_gained: u8,
|
#[prop(default = 0)] opp_holes_gained: u8,
|
||||||
/// True when my hole was scored under bredouille (shows ×2 in the flash).
|
/// True when my hole was scored under bredouille (shows ×2 in the flash).
|
||||||
#[prop(default = false)] my_bredouille: bool,
|
#[prop(default = false)]
|
||||||
|
my_bredouille: bool,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let i18n = use_i18n();
|
let i18n = use_i18n();
|
||||||
|
|
||||||
|
|
@ -89,8 +95,10 @@ pub fn MergedScorePanel(
|
||||||
on_cleanup(move || alive_c.store(false, Ordering::Relaxed));
|
on_cleanup(move || alive_c.store(false, Ordering::Relaxed));
|
||||||
spawn_local(async move {
|
spawn_local(async move {
|
||||||
for p in (my_pts_start + 1)..=my_pts_end {
|
for p in (my_pts_start + 1)..=my_pts_end {
|
||||||
TimeoutFuture::new(200).await;
|
TimeoutFuture::new(100).await;
|
||||||
if !is_alive.load(Ordering::Relaxed) { return; }
|
if !is_alive.load(Ordering::Relaxed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
my_displayed_pts.set(p);
|
my_displayed_pts.set(p);
|
||||||
crate::game::sound::play_points_tick();
|
crate::game::sound::play_points_tick();
|
||||||
}
|
}
|
||||||
|
|
@ -103,20 +111,23 @@ pub fn MergedScorePanel(
|
||||||
on_cleanup(move || alive_c.store(false, Ordering::Relaxed));
|
on_cleanup(move || alive_c.store(false, Ordering::Relaxed));
|
||||||
spawn_local(async move {
|
spawn_local(async move {
|
||||||
for p in (opp_pts_start + 1)..=opp_pts_end {
|
for p in (opp_pts_start + 1)..=opp_pts_end {
|
||||||
TimeoutFuture::new(200).await;
|
TimeoutFuture::new(100).await;
|
||||||
if !is_alive.load(Ordering::Relaxed) { return; }
|
if !is_alive.load(Ordering::Relaxed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
opp_displayed_pts.set(p);
|
opp_displayed_pts.set(p);
|
||||||
|
crate::game::sound::play_opp_points_tick();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Ghost bar widths (show the end value immediately — static reference) ─
|
// ── Ghost bar widths (show the end value immediately — static reference) ─
|
||||||
let my_bar_style = format!("width:{}%", (my_score.points as u32 * 100 / 12).min(100));
|
let my_bar_style = format!("width:{}%", (my_score.points as u32 * 100 / 12).min(100));
|
||||||
let opp_bar_style = format!("width:{}%", (opp_score.points as u32 * 100 / 12).min(100));
|
let opp_bar_style = format!("width:{}%", (opp_score.points as u32 * 100 / 12).min(100));
|
||||||
|
|
||||||
// ── Hole peg tracks ─────────────────────────────────────────────────────
|
// ── Hole peg tracks ─────────────────────────────────────────────────────
|
||||||
let my_holes = my_score.holes;
|
let my_holes = my_score.holes;
|
||||||
let opp_holes = opp_score.holes;
|
let opp_holes = opp_score.holes;
|
||||||
|
|
||||||
let my_pegs: Vec<AnyView> = (1u8..=12)
|
let my_pegs: Vec<AnyView> = (1u8..=12)
|
||||||
|
|
@ -128,7 +139,8 @@ pub fn MergedScorePanel(
|
||||||
class:filled=filled
|
class:filled=filled
|
||||||
class:peg-new=is_new>
|
class:peg-new=is_new>
|
||||||
</div>
|
</div>
|
||||||
}.into_any()
|
}
|
||||||
|
.into_any()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
@ -141,13 +153,14 @@ pub fn MergedScorePanel(
|
||||||
class:filled=filled
|
class:filled=filled
|
||||||
class:peg-new=is_new>
|
class:peg-new=is_new>
|
||||||
</div>
|
</div>
|
||||||
}.into_any()
|
}
|
||||||
|
.into_any()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let my_name = my_score.name.clone();
|
let my_name = my_score.name.clone();
|
||||||
let opp_name = opp_score.name.clone();
|
let opp_name = opp_score.name.clone();
|
||||||
let my_can_bredouille = my_score.can_bredouille;
|
let my_can_bredouille = my_score.can_bredouille;
|
||||||
let opp_can_bredouille = opp_score.can_bredouille;
|
let opp_can_bredouille = opp_score.can_bredouille;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,14 @@ mod inner {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Brief low tick for the jackpot-style points counter (one call per increment).
|
||||||
|
pub fn play_opp_points_tick() {
|
||||||
|
with_ctx(|ctx| {
|
||||||
|
play_tone(ctx, 680.0, 0.18, 0.055, 0.000, OscillatorType::Sine);
|
||||||
|
play_tone(ctx, 1020.0, 0.07, 0.035, 0.000, OscillatorType::Sine);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Triumphant four-note fanfare (C5 – E5 – G5 – C6).
|
/// Triumphant four-note fanfare (C5 – E5 – G5 – C6).
|
||||||
pub fn play_hole_scored() {
|
pub fn play_hole_scored() {
|
||||||
with_ctx(|ctx| {
|
with_ctx(|ctx| {
|
||||||
|
|
@ -175,7 +183,7 @@ mod inner {
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
pub use inner::{
|
pub use inner::{
|
||||||
play_checker_move, play_dice_roll, play_dice_roll_cinematic, play_hole_scored,
|
play_checker_move, play_dice_roll, play_dice_roll_cinematic, play_hole_scored,
|
||||||
play_points_scored, play_points_tick,
|
play_opp_points_tick, play_points_scored, play_points_tick,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
|
@ -189,4 +197,6 @@ pub fn play_points_scored() {}
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub fn play_points_tick() {}
|
pub fn play_points_tick() {}
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
pub fn play_opp_points_tick() {}
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub fn play_hole_scored() {}
|
pub fn play_hole_scored() {}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue