91148fe064
1. 新增物理弹球游戏全套代码,包含物理引擎、规则、渲染、游戏逻辑、存档、音效、UI 2. 新增物理弹球相关调试与单元测试脚本 3. 优化私有剪贴上传功能:增加200MB上传限制与错误提示 4. 修复复古弹球桌的光滑面防粘附与休眠逻辑
60 lines
2.2 KiB
JavaScript
60 lines
2.2 KiB
JavaScript
/* ============================================================
|
|
* pb_audio.js · 物理弹球 Web 复刻版 · WebAudio 合成音效
|
|
* 无外部资源:发射/击中/碎裂/道具/结束 均为振荡器合成。
|
|
* 设置页可开关(PBStorage.soundOn)。
|
|
* ============================================================ */
|
|
var PBAudio = (function () {
|
|
'use strict';
|
|
var ctx = null;
|
|
var lastHit = 0, lastWall = 0; // 分开节流,防砖块命中音被墙壁音吃掉
|
|
|
|
function ac() {
|
|
if (!ctx) {
|
|
try { ctx = new (window.AudioContext || window.webkitAudioContext)(); } catch (e) { ctx = null; }
|
|
}
|
|
if (ctx && ctx.state === 'suspended') { try { ctx.resume(); } catch (e) {} }
|
|
return ctx;
|
|
}
|
|
|
|
function enabled() {
|
|
try { return PBStorage.soundOn(); } catch (e) { return true; }
|
|
}
|
|
|
|
function tone(freq, dur, type, gain, slideTo) {
|
|
var c = ac();
|
|
if (!c || !enabled()) return;
|
|
try {
|
|
var o = c.createOscillator();
|
|
var g = c.createGain();
|
|
o.type = type || 'sine';
|
|
o.frequency.setValueAtTime(freq, c.currentTime);
|
|
if (slideTo) o.frequency.exponentialRampToValueAtTime(slideTo, c.currentTime + dur);
|
|
g.gain.setValueAtTime(gain || 0.08, c.currentTime);
|
|
g.gain.exponentialRampToValueAtTime(0.0001, c.currentTime + dur);
|
|
o.connect(g); g.connect(c.destination);
|
|
o.start(); o.stop(c.currentTime + dur + 0.02);
|
|
} catch (e) {}
|
|
}
|
|
|
|
return {
|
|
unlock: function () { ac(); },
|
|
fire: function () { tone(520, 0.12, 'triangle', 0.06, 260); },
|
|
hit: function (speed) {
|
|
var now = Date.now();
|
|
if (now - lastHit < 45) return; // 限流防炸音
|
|
lastHit = now;
|
|
tone(300 + Math.min(500, speed * 0.15), 0.06, 'square', 0.035);
|
|
},
|
|
wall: function () {
|
|
var now = Date.now();
|
|
if (now - lastWall < 45) return;
|
|
lastWall = now;
|
|
tone(180, 0.05, 'sine', 0.03);
|
|
},
|
|
breakBlock: function () { tone(760, 0.16, 'sawtooth', 0.06, 180); },
|
|
item: function () { tone(660, 0.1, 'sine', 0.07, 990); tone(990, 0.16, 'sine', 0.06, 1320); },
|
|
over: function () { tone(392, 0.25, 'triangle', 0.08, 196); },
|
|
claim: function () { tone(523, 0.09, 'sine', 0.07); tone(659, 0.09, 'sine', 0.07); tone(784, 0.16, 'sine', 0.07); }
|
|
};
|
|
})();
|