Wire remaining voice clips and add glub to ambient loop

Map the new turtvox clips to their matching speech bubbles (tickle replies,
species feeding, playmate greeting/farewell, salve, growth) and add
glub_glub_glub to the ambient underwater loop. Precache new media (v12 -> v13).
This commit is contained in:
Joel Brock
2026-06-20 11:39:48 -07:00
parent 762a698db4
commit 5385e10a41
13 changed files with 40 additions and 13 deletions
+28 -12
View File
@@ -131,13 +131,24 @@ document.addEventListener('DOMContentLoaded', () => {
bittenShell: 'turtvox003_bitten_shell_but_ok.m4a', bittenShell: 'turtvox003_bitten_shell_but_ok.m4a',
somebodysComing: 'turtvox004_somebodys_coming.m4a', somebodysComing: 'turtvox004_somebodys_coming.m4a',
ateBagToxic: 'turtvox005_ate_a_bag_toxic.m4a', ateBagToxic: 'turtvox005_ate_a_bag_toxic.m4a',
propellerStrike: 'turtvox006_propeller_strike_fatal_wound.m4a' propellerStrike: 'turtvox006_propeller_strike_fatal_wound.m4a',
heehee: 'turtvox006_heeheehee.m4a',
morePlease: 'turtvox008_more_please.m4a',
hehe: 'turtvox09_hehe_that_tickles.m4a',
yummySeagrass: 'turtvox011_yummy_seagrass.m4a',
letsPlay: 'turtvox012_another_turtle_lets_play.m4a',
swimSafe: 'turtvox013_swim_safe_friend.m4a',
applyingSalve: 'turtvox014_applying_salve.m4a',
grewALittle: 'turtvox15_I_think_I_grew_a_little.m4a',
crunchyCrab: 'turtvox016_crunchy_crab.m4a',
softJellyfish: 'turtvox017_soft_jellyfish.m4a'
}; };
const WATER_SFX = [ const WATER_SFX = [
'water_sfx_001.m4a', 'water_sfx_001.m4a',
'water_sfx_002.m4a', 'water_sfx_002.m4a',
'water_sfx_003.m4a' 'water_sfx_003.m4a',
'turtvox008_glub_glub_glub.m4a'
]; ];
// Play a single turtle voice line. Autoplay is allowed because the player has // Play a single turtle voice line. Autoplay is allowed because the player has
@@ -549,7 +560,7 @@ document.addEventListener('DOMContentLoaded', () => {
turtleAgeVal.textContent = formatAge(turtleAge); turtleAgeVal.textContent = formatAge(turtleAge);
applyGrowthStage(); applyGrowthStage();
if (wholeDays > 0 && Math.random() > 0.7) { if (wholeDays > 0 && Math.random() > 0.7) {
triggerThoughtBubble(getGrowthThought(), 2200); triggerThoughtBubble(getGrowthThought(), 2200, 'grewALittle');
} }
} }
@@ -1545,7 +1556,7 @@ document.addEventListener('DOMContentLoaded', () => {
updateStatBars(); updateStatBars();
setEyeState('happy'); setEyeState('happy');
setMouthState('normal'); setMouthState('normal');
triggerThoughtBubble(info.greeting, 2200); triggerThoughtBubble(info.greeting, 2200, 'letsPlay');
// Random darting motion around the playpen // Random darting motion around the playpen
const pen = oceanPlaypen.getBoundingClientRect(); const pen = oceanPlaypen.getBoundingClientRect();
@@ -1613,7 +1624,7 @@ document.addEventListener('DOMContentLoaded', () => {
stats.joy = Math.min(100, stats.joy + Math.min(15, highFives * 2)); stats.joy = Math.min(100, stats.joy + Math.min(15, highFives * 2));
updateStatBars(); updateStatBars();
} }
triggerThoughtBubble(info.farewell, 1800); triggerThoughtBubble(info.farewell, 1800, 'swimSafe');
setTimeout(() => setEyeState('normal'), 1200); setTimeout(() => setEyeState('normal'), 1200);
const m = activePlaymate; const m = activePlaymate;
activePlaymate = null; activePlaymate = null;
@@ -1631,7 +1642,7 @@ document.addEventListener('DOMContentLoaded', () => {
setTimeout(() => setEyeState('normal'), 2000); setTimeout(() => setEyeState('normal'), 2000);
} else if (stats.health < 80) { } else if (stats.health < 80) {
stats.health = Math.min(100, stats.health + 20); stats.health = Math.min(100, stats.health + 20);
triggerThoughtBubble("Applying salve... 🩹"); triggerThoughtBubble("Applying salve... 🩹", 3000, 'applyingSalve');
} else { } else {
triggerThoughtBubble("I feel great! 🐢"); triggerThoughtBubble("I feel great! 🐢");
} }
@@ -1695,17 +1706,17 @@ document.addEventListener('DOMContentLoaded', () => {
if (foodType === 'seagrass' && turtleSpecies === 'green') { if (foodType === 'seagrass' && turtleSpecies === 'green') {
stats.hunger = Math.min(100, stats.hunger + 30); stats.hunger = Math.min(100, stats.hunger + 30);
stats.joy = Math.min(100, stats.joy + 10); stats.joy = Math.min(100, stats.joy + 10);
triggerThoughtBubble("Yummy seagrass! 🌿"); triggerThoughtBubble("Yummy seagrass! 🌿", 3000, 'yummySeagrass');
setEyeState('happy'); setEyeState('happy');
} else if (foodType === 'crabs' && turtleSpecies === 'loggerhead') { } else if (foodType === 'crabs' && turtleSpecies === 'loggerhead') {
stats.hunger = Math.min(100, stats.hunger + 30); stats.hunger = Math.min(100, stats.hunger + 30);
stats.joy = Math.min(100, stats.joy + 10); stats.joy = Math.min(100, stats.joy + 10);
triggerThoughtBubble("Crunchy crab! 🦀"); triggerThoughtBubble("Crunchy crab! 🦀", 3000, 'crunchyCrab');
setEyeState('happy'); setEyeState('happy');
} else if (foodType === 'jellyfish' && turtleSpecies === 'leatherback') { } else if (foodType === 'jellyfish' && turtleSpecies === 'leatherback') {
stats.hunger = Math.min(100, stats.hunger + 30); stats.hunger = Math.min(100, stats.hunger + 30);
stats.joy = Math.min(100, stats.joy + 10); stats.joy = Math.min(100, stats.joy + 10);
triggerThoughtBubble("Soft jellyfish! 🪼"); triggerThoughtBubble("Soft jellyfish! 🪼", 3000, 'softJellyfish');
setEyeState('happy'); setEyeState('happy');
} else { } else {
stats.hunger = Math.min(100, stats.hunger + 12); stats.hunger = Math.min(100, stats.hunger + 12);
@@ -2457,9 +2468,14 @@ document.addEventListener('DOMContentLoaded', () => {
turtleContainer.classList.remove('being-tickled'); turtleContainer.classList.remove('being-tickled');
setEyeState('normal'); setEyeState('normal');
if (rubCount >= 3) { if (rubCount >= 3) {
const thoughts = ["Hehe that tickles! ✨", "More please! 💕", "Best human ever! 🥰", "Hehehehe! 😆"]; const tickleThoughts = [
const pick = thoughts[Math.floor(Math.random() * thoughts.length)]; { text: "Hehe that tickles! ✨", voice: 'hehe' },
triggerThoughtBubble(pick, 1800, pick.startsWith('Best human') ? 'bestHuman' : null); { text: "More please! 💕", voice: 'morePlease' },
{ text: "Best human ever! 🥰", voice: 'bestHuman' },
{ text: "Hehehehe! 😆", voice: 'heehee' }
];
const pick = tickleThoughts[Math.floor(Math.random() * tickleThoughts.length)];
triggerThoughtBubble(pick.text, 1800, pick.voice);
stats.joy = Math.min(100, stats.joy + 5); stats.joy = Math.min(100, stats.joy + 5);
updateStatBars(); updateStatBars();
} }
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+12 -1
View File
@@ -1,4 +1,4 @@
const CACHE_NAME = 'tortugotchi-v12'; const CACHE_NAME = 'tortugotchi-v13';
const ASSETS = [ const ASSETS = [
'./', './',
'./index.html', './index.html',
@@ -13,6 +13,17 @@ const ASSETS = [
'./media/turtvox004_somebodys_coming.m4a', './media/turtvox004_somebodys_coming.m4a',
'./media/turtvox005_ate_a_bag_toxic.m4a', './media/turtvox005_ate_a_bag_toxic.m4a',
'./media/turtvox006_propeller_strike_fatal_wound.m4a', './media/turtvox006_propeller_strike_fatal_wound.m4a',
'./media/turtvox006_heeheehee.m4a',
'./media/turtvox008_more_please.m4a',
'./media/turtvox008_glub_glub_glub.m4a',
'./media/turtvox09_hehe_that_tickles.m4a',
'./media/turtvox011_yummy_seagrass.m4a',
'./media/turtvox012_another_turtle_lets_play.m4a',
'./media/turtvox013_swim_safe_friend.m4a',
'./media/turtvox014_applying_salve.m4a',
'./media/turtvox15_I_think_I_grew_a_little.m4a',
'./media/turtvox016_crunchy_crab.m4a',
'./media/turtvox017_soft_jellyfish.m4a',
'./media/water_sfx_001.m4a', './media/water_sfx_001.m4a',
'./media/water_sfx_002.m4a', './media/water_sfx_002.m4a',
'./media/water_sfx_003.m4a' './media/water_sfx_003.m4a'