宝宝踢腿配一声轻「噗」音效;广场示例帖点赞每天 +20~30(GC_LIKES)(v26110439)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
deploy
2026-11-05 00:54:25 +00:00
parent c4c9b9e9fd
commit fdeec91857
27 changed files with 135 additions and 91 deletions

View File

@@ -119,6 +119,34 @@
}
const kick = () => { if (!raf && ready) raf = requestAnimationFrame(loop); };
/* 11-05 用户:「踢的时候给一个小音效,不要持续,只有踢的时候给一点点」
→ 只在小腿 / 小脚动(=踢)时响一声,小胳膊动不响;WebAudio 现场合成一声很轻的「噗」(隔着水的低沉闷响 + 一个极轻的小气泡),约 0.2 秒、音量很小,不加载音频文件。
· 浏览器规定用户碰过页面后才能出声 → 第一次点 / 摸屏幕时才建 AudioContext,之前的踢腿不响。
· 页面在后台 / 首页不在前台时本来就不动,也就不响;系统「减少动态效果」整个文件不跑。
· URL 带 kicksound=0 关掉(调试用)。 */
let ac = null;
const soundOff = /[?&#]kicksound=0/.test(location.href);
const unlock = () => {
if (ac || soundOff) return;
try { const A = window.AudioContext || window.webkitAudioContext; if (A) { ac = new A(); if (ac.state === 'suspended') ac.resume(); } } catch (e) { ac = null; }
};
['touchstart', 'pointerdown', 'click'].forEach(t => addEventListener(t, unlock, { passive: true, once: false, capture: true }));
function kickSound(delay) {
if (!ac || ac.state !== 'running') return;
const t = ac.currentTime + delay / 1000;
// 闷响:正弦 150→60Hz 快速下滑,低通滤掉高频,像隔着肚皮
const o = ac.createOscillator(), g = ac.createGain(), lp = ac.createBiquadFilter();
o.type = 'sine'; o.frequency.setValueAtTime(150, t); o.frequency.exponentialRampToValueAtTime(60, t + .16);
lp.type = 'lowpass'; lp.frequency.value = 420;
g.gain.setValueAtTime(0.0001, t); g.gain.exponentialRampToValueAtTime(0.16, t + .012); g.gain.exponentialRampToValueAtTime(0.0001, t + .2);
o.connect(lp); lp.connect(g); g.connect(ac.destination); o.start(t); o.stop(t + .22);
// 小气泡:很轻的上滑「啵」,晚一点点
const b = ac.createOscillator(), bg = ac.createGain(), t2 = t + .05;
b.type = 'sine'; b.frequency.setValueAtTime(520, t2); b.frequency.exponentialRampToValueAtTime(900, t2 + .07);
bg.gain.setValueAtTime(0.0001, t2); bg.gain.exponentialRampToValueAtTime(0.025, t2 + .01); bg.gain.exponentialRampToValueAtTime(0.0001, t2 + .09);
b.connect(bg); bg.connect(ac.destination); b.start(t2); b.stop(t2 + .1);
}
// 安排下一次「动一动」
function plan() {
clearTimeout(timer);
@@ -134,6 +162,7 @@
const f = cfg.l.findIndex(x => x[6] === 'foot');
if (l[6] === 'leg' && f >= 0 && Math.random() < .4)
moves.push({ i: f, t0: now + 300, dur: dur - 200, amp: -dir * cfg.l[f][5] * .7 * (DEBUG ? 4 : 1) * Math.PI / 180 });
if (l[6] === 'leg' || l[6] === 'foot') kickSound(dur * .3); // 踢到最快那一下时响(缓起缓落,约 3 成处)
kick();
}
plan();