improvfmeents

This commit is contained in:
Michal Vrba
2026-09-04 11:31:52 +02:00
parent 7ca0e08637
commit d4e0071f95
14 changed files with 941 additions and 61 deletions
+189
View File
@@ -39,6 +39,17 @@ window.FaraonFx = (function () {
return audioCtx;
}
// Automatické prebudenie AudioContextu pri prvom kliknutí používateľa kdekoľvek
if (typeof window !== 'undefined') {
const unlockAudio = () => {
getAudioContext();
window.removeEventListener('pointerdown', unlockAudio);
window.removeEventListener('keydown', unlockAudio);
};
window.addEventListener('pointerdown', unlockAudio, { passive: true });
window.addEventListener('keydown', unlockAudio, { passive: true });
}
// --- PROCEDURAL SOUND GENERATORS ---
function playCardSnap() {
if (isMuted) return;
@@ -386,6 +397,182 @@ window.FaraonFx = (function () {
});
}
function playCardWhoosh() {
if (isMuted) return;
const ctx = getAudioContext();
if (!ctx) return;
const now = ctx.currentTime;
const bufferSize = Math.floor(ctx.sampleRate * 0.22);
const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
const data = buffer.getChannelData(0);
for (let i = 0; i < bufferSize; i++) {
data[i] = (Math.random() * 2 - 1) * Math.sin((i / bufferSize) * Math.PI);
}
const noise = ctx.createBufferSource();
noise.buffer = buffer;
const filter = ctx.createBiquadFilter();
filter.type = 'bandpass';
filter.frequency.setValueAtTime(450, now);
filter.frequency.exponentialRampToValueAtTime(1200, now + 0.1);
filter.frequency.exponentialRampToValueAtTime(350, now + 0.22);
filter.Q.value = 2.5;
const gain = ctx.createGain();
gain.gain.setValueAtTime(0.3, now);
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.22);
noise.connect(filter);
filter.connect(gain);
gain.connect(ctx.destination);
noise.start(now);
}
function playBotPersonalitySfx(personalityId, emotion) {
if (isMuted) return;
const ctx = getAudioContext();
if (!ctx) return;
const now = ctx.currentTime;
const pId = (personalityId || 'fox').toLowerCase();
const emo = (emotion || 'thinking').toLowerCase();
// Mierny posun tóniny podľa emócie
let pitchMul = 1.0;
if (emo === 'shocked' || emo === 'desperate') pitchMul = 0.82;
else if (emo === 'confident' || emo === 'celebrating') pitchMul = 1.22;
else if (emo === 'freezing') pitchMul = 1.45;
else if (emo === 'angry') pitchMul = 0.92;
switch (pId) {
case 'fox': { // Lišiak Filip - sly playful rising arpeggio
const baseFreqs = [440, 554.37, 659.25, 880];
baseFreqs.forEach((freq, i) => {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
const t = now + i * 0.045;
osc.type = 'triangle';
osc.frequency.setValueAtTime(freq * pitchMul, t);
gain.gain.setValueAtTime(0.28, t);
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.18);
osc.connect(gain);
gain.connect(ctx.destination);
osc.start(t);
osc.stop(t + 0.19);
});
break;
}
case 'queen': { // Kráľovná Alžbeta - regal royal chime / bell chords
const baseFreqs = [523.25, 659.25, 783.99, 1046.50];
baseFreqs.forEach((freq, i) => {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
const t = now + i * 0.055;
osc.type = 'sine';
osc.frequency.setValueAtTime(freq * pitchMul, t);
gain.gain.setValueAtTime(0.32, t);
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.42);
osc.connect(gain);
gain.connect(ctx.destination);
osc.start(t);
osc.stop(t + 0.43);
});
break;
}
case 'robot': { // Kyber-Robo - 8-bit digital synth crunch
const tones = [880, 1320, 660, 1760];
tones.forEach((freq, i) => {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
const t = now + i * 0.04;
osc.type = 'square';
osc.frequency.setValueAtTime(freq * pitchMul, t);
gain.gain.setValueAtTime(0.22, t);
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.06);
osc.connect(gain);
gain.connect(ctx.destination);
osc.start(t);
osc.stop(t + 0.065);
});
break;
}
case 'grandpa': { // Dedo Jozef - warm vintage harmonic bell
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.type = 'sine';
osc.frequency.setValueAtTime(987.77 * pitchMul, now);
gain.gain.setValueAtTime(0.35, now);
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.55);
osc.connect(gain);
gain.connect(ctx.destination);
osc.start(now);
osc.stop(now + 0.56);
break;
}
case 'cyberkid': { // Hacker Miško - futuristic laser zap
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.type = 'sawtooth';
osc.frequency.setValueAtTime(1500 * pitchMul, now);
osc.frequency.exponentialRampToValueAtTime(180 * pitchMul, now + 0.18);
gain.gain.setValueAtTime(0.3, now);
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.18);
osc.connect(gain);
gain.connect(ctx.destination);
osc.start(now);
osc.stop(now + 0.19);
break;
}
case 'cat': { // Mačka Minda - playful synth meow
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.type = 'sine';
osc.frequency.setValueAtTime(580 * pitchMul, now);
osc.frequency.exponentialRampToValueAtTime(980 * pitchMul, now + 0.11);
osc.frequency.exponentialRampToValueAtTime(680 * pitchMul, now + 0.28);
gain.gain.setValueAtTime(0.32, now);
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.30);
osc.connect(gain);
gain.connect(ctx.destination);
osc.start(now);
osc.stop(now + 0.31);
break;
}
case 'wizard': { // Čarodejník Baltazár - mystical shimmering chord
[392.00, 587.33, 880.00, 1174.66].forEach((freq, i) => {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
const t = now + i * 0.035;
osc.type = 'sine';
osc.frequency.setValueAtTime(freq * pitchMul, t);
gain.gain.setValueAtTime(0.24, t);
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.45);
osc.connect(gain);
gain.connect(ctx.destination);
osc.start(t);
osc.stop(t + 0.46);
});
break;
}
case 'bear': { // Medveď Mišo - deep bass growl thud
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.type = 'sawtooth';
osc.frequency.setValueAtTime(95 * pitchMul, now);
osc.frequency.exponentialRampToValueAtTime(38 * pitchMul, now + 0.35);
gain.gain.setValueAtTime(0.42, now);
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.35);
osc.connect(gain);
gain.connect(ctx.destination);
osc.start(now);
osc.stop(now + 0.36);
break;
}
default: {
playCardSnap();
break;
}
}
}
// --- SCREEN SHAKE ---
function triggerScreenShake(intensity = 5) {
const board = document.getElementById('game-table-container');
@@ -1197,6 +1384,8 @@ window.FaraonFx = (function () {
animateCardPlay,
animateCardDraw,
animateTurnTransition,
playCardWhoosh,
playBotPersonalitySfx,
setSpeedLevel,
toggleMute
};