资讯详情

资讯详情

Turbulenz Engine SoundManager 声音加载与管理指南

游戏开发图形学【免费下载链接】turbulenz_engineTurbulenz is a modular 3D and 2D game framework for making HTML5 powered games for browsers, desktops and mobile devices.项目地址https://gitcode.com/gh_mirrors/tu/turbulenz_engine点击查看免费下载导读SoundManager 是 Turbulenz Engine 中负责声音资源加载与统一管理的核心对象它按路径维护声音映射以避免重复加载在声音缺失或尚未加载完成时自动回退到默认声音并提供load、get、map、reload、setPathRemapping等一组实用的管理接口。阅读本文后你将掌握 SoundManager 的完整 API 用法、异步加载的正确协作模式以及如何结合 MappingTable 实现声音资源的路径重映射从而在 HTML5 游戏中高效、稳健地管理音频资源。SoundManager 的设计职责根据官方 API 文档 soundmanager_api.rst 的描述SoundManager 提供以下核心能力按路径去重内部维护一张已请求路径 → 声音对象的映射表sounds同一路径只发起一次加载请求避免重复下载默认声音回退当请求的声音缺失或尚未加载完成时返回默认声音保证上层逻辑不会因空引用而崩溃异步加载模型声音加载是异步操作应用需要在每帧或定时任务中周期检查加载进度再统一更新声音引用路径重映射Remapping支持通过映射表重定向实际加载 URL便于服务器迁移、CDN 部署等场景。从源码 soundmanager.ts 可以看到其内部数据结构var sounds {}; // path - Sound已加载完成的声音 var loadingSound {}; // path - true正在加载中的声音 var numLoadingSounds 0; // 正在加载的声音计数 var pathRemapping null; // 路径重映射字典 var pathPrefix ; // 全局路径前缀必需脚本与依赖SoundManager 的 TypeScript 源码 soundmanager.ts 明确依赖两个模块/*{{ javascript(jslib/soundmanager.js) }}*/ /*{{ javascript(jslib/observer.js) }}*/其中 observer.ts 提供观察者模式支持当多个调用方对同一路径发起load时后到的回调通过Observer订阅到同一次加载事件上加载完成后统一被notify。此外 SoundManager 还间接依赖RequestHandler负责实际网络请求与SoundDevice负责创建、解码声音对象这两者的完整 API 参见 requesthandler_api.rst 与 sound_api.rst。创建 SoundManagercreate语法与参数var soundManager SoundManager.create(soundDevice, requestHandler, defaultSound, errorCallback);参数类型说明soundDeviceSoundDevice用于创建和加载单个声音对象的设备对象由TurbulenzEngine.createSoundDevice()获得requestHandlerRequestHandler负责资源网络请求的对象defaultSound可选Sound请求的声音不可用时的默认回退声音缺省时使用一个烦人的长哔声帮助开发者定位缺失的声音errorCallback可选function(msg)管理器运行期间发生任何错误时的回调默认声音的实现细节源码 soundmanager.ts 展示了默认声音的生成方式当未传入defaultSound时SoundManager 会调用内部工具方法SoundManager.beep(1.0, 4000, 400, 1)动态生成一段 1 秒、采样率 4000 Hz、波形频率 400 Hz 的方波数据并通过sd.createSound()创建为名为default的声音对象若创建失败则调用errorCallback(Default sound not created.)。这段哔声以sounds[default]的形式注册进映射表是所有缺失声音的兜底。如果传入errorCallback为空源码会自动替换为一个空函数因此该参数可以安全省略。与设备/请求器的配合创建真实项目中 SoundManager 通常在其他管理器之后创建模式如下参考 sound.ts 示例var soundDeviceParameters { linearDistance : false }; var soundDevice TurbulenzEngine.createSoundDevice(soundDeviceParameters); if (!soundDevice) { errorCallback(No SoundDevice detected.); return; } var requestHandler RequestHandler.create({}); var soundManager SoundManager.create(soundDevice, requestHandler, null, errorCallback);注意createSoundDevice是 turbulenzengine.ts 上的引擎级方法每个引擎实例只能创建一次重复调用会触发错误回调并返回null。加载声音load与异步协作模式语法与参数var onload function onloadFn(sound) {}; var sound soundManager.load(path, uncompress, onload);参数类型说明pathstring要加载的声音 URLuncompress可选boolean是否在内存中解压全部声音数据解压会增加内存占用但消除 CPU 解码开销仅在需要同时播放大量压缩声音时才需要开启onload可选function(sound)声音加载完成后的异步回调参数为加载好的 Sound 对象返回值如果该路径声音已加载完成返回对应的 Sound否则返回默认声音。onload回调始终以异步方式被调用——源码 soundmanager.ts 中即使声音已经加载完毕也会通过TurbulenzEngine.setTimeout(..., 0)延后执行回调保证调用方行为一致。去重与多回调订阅机制源码 soundmanager.ts 揭示了load的内部逻辑若sounds[path]已存在直接返回或异步触发onload若该路径正在加载loadingSound[path]为 true将新的onload通过Observer.subscribe()追加到同一加载事件否则发起新请求计数numLoadingSounds 1通过RequestHandler.request({ src, requestFn, onload })获取资源再由sd.createSound({ src: url, uncompress: uncompress, onload: onload })解码成声音对象加载成功后写入sounds[path]并observer.notify(sound)通知所有订阅者加载失败则delete sounds[path]并递减numLoadingSounds。等待加载完成的轮询模式由于加载是异步的文档推荐在更新所有声音引用之前周期性地检查加载状态// 每隔一段时间检查一次 var numPendingSounds soundManager.getNumPendingSounds(); if (numPendingSounds) { keepWaiting(); // 还有声音未加载完成继续等待 }if (soundManager.isSoundLoaded(path)) { noMoreWaiting(); // 该路径声音已就绪 } if (soundManager.isSoundMissing(path)) { errorWhilstLoading(); // 该路径声音缺失加载失败或尚未成功 }这三个查询方法的实现同样位于 soundmanager.tsgetNumPendingSounds()直接返回内部计数器numLoadingSounds统计所有仍在加载中的声音数量isSoundLoaded(path)返回!loadingSound[path]即该路径不在加载队列中即视为已加载包括缺失的情况isSoundMissing(path)返回!sounds[path]即映射表中没有该路径的可用声音对象。一个典型的做法是先用getNumPendingSounds()判断全局加载是否结束再用isSoundLoaded/isSoundMissing逐路径细分处理避免在声音尚未就绪时就开始播放。获取与别名get与mapget(path)var sound soundManager.get(path);返回存储在给定路径下的已加载声音对象如果该声音缺失或尚未加载完成则返回默认声音源码 soundmanager.ts 中的getSound逻辑。由于get永远不会返回null上层可以放心地拿返回值直接播放这也是 SoundManager 提升健壮性的关键设计。map(alias, name)soundManager.map(alias, name);为已加载的声音建立别名name是待映射的原始名称alias是新别名。源码实现非常轻量var mapSound function mapSoundFn(dst, src) { sounds[dst] sounds[src]; };即把sounds[name]的引用同时登记到sounds[alias]下之后用get(alias)也能取到同一个声音对象。注意map只是引用复制不会触发任何网络加载因此应先确保name对应的声音已加载完成。移除与重载remove/reload/reloadAllremove(path)soundManager.remove(path);从映射表中删除指定路径存储的声音源码removeSound执行delete sounds[path]。该操作只删除管理器中的引用并不会立即销毁声音对象本身。reload(path)soundManager.reload(path);重新加载指定路径的声音适用于服务器端声音文件已更新、应用希望获取最新版本的场景。源码实现是先移除、再加载的组合var reloadSound function reloadSoundFn(path) { removeSound(path); loadSound(path); };重载是异步过程加载完成后同样通过回调通知调用方。reloadAll()soundManager.reloadAll();遍历重载全部已存储的声音默认声音default除外源码 soundmanager.ts 中通过t ! defaultSoundName排除。文档特别提示该操作可能耗时较长且全程异步完成适合服务器端批量更新了大量声音资源后的整体刷新场景。路径重映射setPathRemapping语法与参数soundManager.setPathRemapping(mappingDictionary, prefix);参数类型说明mappingDictionaryobject重映射表用于将特定逻辑路径重定向到物理路径prefixstring追加到所有路径的前缀字符串适合全局重定向两个关键语义需要牢记重映射只影响加载 URL声音仍然以最初请求的原始路径作为键存储在映射表中get(path)时仍使用逻辑路径重映射必须在渲染器创建之前完成文档明确警告——如果重映射对查找 shader 是必需的则必须在 renderer 创建之前调用如果在之后进行部分 shader 可能无法正确加载。与 MappingTable 的配合文档给出的典型用法是配合 Turbulenz Services 的 MappingTable 使用。mappingDictionary与prefix分别对应 MappingTable 对象的urlMapping与assetPrefix两个属性var mappingTableReceived function mappingTableReceivedFn(mappingTable) { soundManager.setPathRemapping(mappingTable.urlMapping, mappingTable.assetPrefix); }; mappingTable TurbulenzServices.createMappingTable(gameSession, mappingTableReceived);从源码 mappingtable.ts 看MappingTable 的getURL(assetPath)逻辑是先在urlMapping中精确查找命中则返回物理路径未命中则返回assetPrefix assetPath——这与 SoundManager 内部的重映射策略(pathRemapping pathRemapping[path]) || (pathPrefix path)完全对应。实际项目中sound.ts 示例 还展示了先通过mappingTable.getURL(sounds/duck.ogg)获取映射后的 URL再交给soundDevice.createSound加载的另一种更直接的用法并会依据soundDevice.isSupported(FILEFORMAT_OGG)在 Ogg 与 MP3 之间选择资源。生成哔声beepvar beepSound soundManager.beep(frequency, wavefrequency, length);参数类型说明frequencynumber哔声的采样率即每秒采样点数wavefrequencynumber哔声波形的频率Hzlengthnumber哔声时长秒文档指出默认声音正是由beep(4000, 400, 1)生成的对应源码中振幅 1.0 的调用SoundManager.beep(1.0, 4000, 400, 1)。其实现soundmanager.ts用正弦波逐样本合成 PCM 数据dphi 2π × wavefrequency / frequency控制每个采样点的相位增量循环生成frequency × length个采样当运行环境支持Float32Array时使用类型化数组否则退化为普通Array。beep是静态工具方法可用于快速生成提示音或测试音。释放资源destroysoundManager.destroy();释放 SoundManager 及其分配的所有资源。调用后管理器对象以及它所引用的声音对象都将失效。源码 soundmanager.ts 的清理流程包括遍历sounds映射表逐一调用sound.destroy()释放每个声音置空内部引用sounds、defaultSound、loadingSound、loadedObservers、pathRemapping、pathPrefix、rh、sd清零numLoadingSounds。注意每个 Sound 对象自身的destroy()见 sounddevice.ts 中WebGLSound.destroy还会通过URL.revokeObjectURL回收其 Blob URL实现完整的内存释放。版本属性versionvar versionNumber soundManager.version;version是 SoundManager 实现的版本号当前源码中为static version 1可用于运行时的特性探测与兼容性判断。完整实践加载并播放一段声音综合以上 API一个完整的声音加载与播放流程如下参照 sound.ts 示例 的资源加载风格TurbulenzEngine.onload function onloadFn() { var errorCallback function errorCallbackFn(msg) { window.alert(msg); }; var soundDevice TurbulenzEngine.createSoundDevice({}); if (!soundDevice) { errorCallback(No SoundDevice detected.); return; } var requestHandler RequestHandler.create({}); var soundManager SoundManager.create(soundDevice, requestHandler, null, errorCallback); // 根据浏览器支持的格式选择资源 var soundURL soundDevice.isSupported(FILEFORMAT_OGG) ? sounds/duck.ogg : sounds/duck.mp3; soundManager.load(soundURL, false, function onSoundLoadedFn(sound) { // 异步回调此时声音已可播放 var source soundDevice.createSource(sound); source.play(); }); // 主循环中轮询加载状态 var loadingLoop function loadingLoopFn() { if (soundManager.getNumPendingSounds() 0 soundManager.isSoundLoaded(soundURL)) { // 全部声音就绪开始正常游戏循环 startGameLoop(); } }; TurbulenzEngine.setInterval(loadingLoop, 1000 / 10); };上述示例中的音频资源sounds/duck.ogg、sounds/duck.mp3均存在于仓库的 assets/sounds 目录下可直接替换为实际项目中的声音路径。相关 API 与延伸阅读SoundManager 处于声音子系统的最上层与其协作的核心对象还包括SoundManager 源码本文所有 API 行为的最终实现依据Sound API 文档load/get返回的 Sound 对象自身的方法与属性SoundDevice API 文档createSound、createSource、isSupported等底层能力RequestHandler API 文档request({ src, requestFn, onload })的网络请求语义与重试策略MappingTable API 文档urlMapping/assetPrefix的完整定义Observer 源码load多回调订阅与通知的底层机制。通过 SoundManager SoundDevice RequestHandler 的组合Turbulenz Engine 应用可以在不关心网络细节的前提下获得去重、兜底、重载、路径重映射等完整的声音资源生命周期管理能力。赞分享游戏开发图形学【免费下载链接】turbulenz_engineTurbulenz is a modular 3D and 2D game framework for making HTML5 powered games for browsers, desktops and mobile devices.项目地址https://gitcode.com/gh_mirrors/tu/turbulenz_engine点击查看免费下载相关推荐3分钟搭建跨平台文件服务器HFS2极速上手指南3分钟搭建跨平台文件服务器HFS2极速上手指南 还在为跨平台文件共享烦恼吗传统FTP配置复杂云存储又有隐私顾虑。HFS2HTTP File Server游戏开发图形学Turbulenz Engine 声音对象Sound完全指南从音频加载到播放的属性与方法详解Turbulenz Engine 声音对象Sound完全指南从音频加载到播放的属性与方法详解 Sound 对象是 Turbulenz Engine 音频系游戏开发图形学从零到一的机器人开发robotics-coursework项目实战教程从零到一的机器人开发robotics coursework项目实战教程 想要学习机器人开发却不知从何开始robotics coursework项目为你提供了文档教程上一篇TV Bro 电视浏览器怎么上手用遥控器浏览网页的完整指南下一篇5万条微信记录2分钟导完PyWxDump本地备份完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →