Phaser 音频系统 #
音频概述 #
Phaser 使用 Web Audio API 和 HTML5 Audio 提供强大的音频支持。
text
┌─────────────────────────────────────────────────────────────┐
│ 音频系统架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Sound Manager │
│ ├── Web Audio API │
│ │ ├── 低延迟 │
│ │ ├── 音频节点 │
│ │ └── 音效处理 │
│ ├── HTML5 Audio │
│ │ ├── 兼容性好 │
│ │ └── 功能有限 │
│ └── 音频类型 │
│ ├── 音效(SFX) │
│ └── 背景音乐(BGM) │
│ │
└─────────────────────────────────────────────────────────────┘
加载音频 #
基本加载 #
javascript
preload() {
this.load.audio('bgm', 'assets/audio/background.mp3');
this.load.audio('jump', 'assets/audio/jump.mp3');
this.load.audio('coin', 'assets/audio/coin.mp3');
this.load.audio('explosion', 'assets/audio/explosion.mp3');
}
多格式支持 #
javascript
preload() {
this.load.audio('bgm', [
'assets/audio/background.mp3',
'assets/audio/background.ogg',
'assets/audio/background.m4a'
]);
}
音频精灵 #
javascript
preload() {
this.load.audioSprite('sfx', 'assets/audio/sfx.json', [
'assets/audio/sfx.mp3',
'assets/audio/sfx.ogg'
]);
}
播放音频 #
基本播放 #
javascript
create() {
this.sound.play('jump');
this.bgm = this.sound.add('bgm');
this.bgm.play();
this.coinSound = this.sound.add('coin');
this.coinSound.play();
}
播放配置 #
javascript
this.sound.play('jump', {
volume: 0.5,
rate: 1,
detune: 0,
seek: 0,
loop: false,
delay: 0
});
const sound = this.sound.add('bgm', {
volume: 0.3,
loop: true
});
sound.play();
音频精灵播放 #
javascript
create() {
this.sound.playAudioSprite('sfx', 'jump');
this.sfx = this.sound.addAudioSprite('sfx');
this.sfx.play('coin');
this.sfx.play('explosion');
}
音频控制 #
音量控制 #
javascript
const sound = this.sound.add('bgm');
sound.setVolume(0.5);
sound.volume = 0.5;
this.sound.setVolume(0.5);
this.sound.volume = 0.5;
暂停与恢复 #
javascript
const sound = this.sound.add('bgm');
sound.play();
sound.pause();
sound.resume();
sound.stop();
sound.destroy();
循环播放 #
javascript
const sound = this.sound.add('bgm', { loop: true });
sound.play();
sound.setLoop(true);
const isLooping = sound.loop;
播放速率 #
javascript
const sound = this.sound.add('bgm');
sound.setRate(1.5);
sound.rate = 1.5;
sound.setDetune(100);
sound.detune = 100;
播放位置 #
javascript
const sound = this.sound.add('bgm');
sound.setSeek(30);
sound.seek = 30;
const currentTime = sound.seek;
const duration = sound.duration;
const progress = sound.seek / sound.duration;
静音 #
javascript
const sound = this.sound.add('bgm');
sound.setMute(true);
sound.mute = true;
this.sound.setMute(true);
this.sound.mute = true;
音频事件 #
声音事件 #
javascript
const sound = this.sound.add('bgm');
sound.on('play', (sound) => {
console.log('Sound started playing');
});
sound.on('end', (sound) => {
console.log('Sound ended');
});
sound.on('stop', (sound) => {
console.log('Sound stopped');
});
sound.on('pause', (sound) => {
console.log('Sound paused');
});
sound.on('resume', (sound) => {
console.log('Sound resumed');
});
sound.on('loop', (sound) => {
console.log('Sound looped');
});
sound.on('mute', (sound, mute) => {
console.log('Mute changed:', mute);
});
sound.on('volume', (sound, volume) => {
console.log('Volume changed:', volume);
});
sound.on('rate', (sound, rate) => {
console.log('Rate changed:', rate);
});
sound.on('seek', (sound, seek) => {
console.log('Seek changed:', seek);
});
全局事件 #
javascript
this.sound.on('mute', (soundManager, mute) => {
console.log('Global mute:', mute);
});
this.sound.on('volume', (soundManager, volume) => {
console.log('Global volume:', volume);
});
this.sound.on('unlocked', () => {
console.log('Audio unlocked');
});
音频管理 #
获取音频 #
javascript
const allSounds = this.sound.getAll();
const sound = this.sound.get('bgm');
const isPlaying = this.sound.isPlaying('bgm');
const isPaused = this.sound.isPaused('bgm');
停止所有音频 #
javascript
this.sound.stopAll();
this.sound.stopByKey('bgm');
音频解锁 #
javascript
if (this.sound.locked) {
this.sound.once('unlocked', () => {
this.sound.play('bgm');
});
}
this.input.once('pointerdown', () => {
this.sound.unlock();
});
音频效果 #
淡入淡出 #
javascript
const sound = this.sound.add('bgm', { volume: 0 });
sound.play();
this.tweens.add({
targets: sound,
volume: 1,
duration: 2000,
ease: 'Linear'
});
this.tweens.add({
targets: sound,
volume: 0,
duration: 2000,
ease: 'Linear',
onComplete: () => sound.stop()
});
音量渐变 #
javascript
fadeIn(sound, duration = 1000) {
sound.setVolume(0);
sound.play();
this.tweens.add({
targets: sound,
volume: 1,
duration: duration,
ease: 'Linear'
});
}
fadeOut(sound, duration = 1000) {
this.tweens.add({
targets: sound,
volume: 0,
duration: duration,
ease: 'Linear',
onComplete: () => sound.stop()
});
}
crossFade(fromSound, toSound, duration = 1000) {
this.tweens.add({
targets: fromSound,
volume: 0,
duration: duration,
ease: 'Linear',
onComplete: () => fromSound.stop()
});
toSound.setVolume(0);
toSound.play();
this.tweens.add({
targets: toSound,
volume: 1,
duration: duration,
ease: 'Linear'
});
}
随机音高 #
javascript
playWithRandomPitch(key) {
const sound = this.sound.add(key);
sound.setDetune(Phaser.Math.Between(-200, 200));
sound.play();
}
3D 音频 #
javascript
playPositionalSound(key, sourceX, sourceY, listenerX, listenerY, maxDistance) {
const distance = Phaser.Math.Distance.Between(sourceX, sourceY, listenerX, listenerY);
const volume = Math.max(0, 1 - distance / maxDistance);
const sound = this.sound.add(key, { volume: volume });
sound.play();
const angle = Phaser.Math.Angle.Between(listenerX, listenerY, sourceX, sourceY);
const pan = Math.cos(angle);
return sound;
}
音频配置 #
全局配置 #
javascript
const config = {
audio: {
disableWebAudio: false,
noAudio: false
}
};
音频上下文 #
javascript
const context = this.sound.context;
const masterGain = this.sound.masterGain;
音频池 #
音效池 #
javascript
class SoundPool {
constructor(scene, key, poolSize = 5) {
this.scene = scene;
this.key = key;
this.pool = [];
for (let i = 0; i < poolSize; i++) {
this.pool.push(scene.sound.add(key));
}
}
play(config = {}) {
const sound = this.pool.find(s => !s.isPlaying);
if (sound) {
sound.play(config);
return sound;
}
return null;
}
}
create() {
this.jumpSoundPool = new SoundPool(this, 'jump', 10);
}
update() {
if (playerJumped) {
this.jumpSoundPool.play();
}
}
完整示例 #
音频管理器 #
javascript
class AudioManager {
constructor(scene) {
this.scene = scene;
this.bgm = null;
this.sfxVolume = 1;
this.bgmVolume = 0.5;
this.muted = false;
}
playBGM(key, config = {}) {
if (this.bgm) {
this.stopBGM();
}
this.bgm = this.scene.sound.add(key, {
volume: this.bgmVolume,
loop: true,
...config
});
this.bgm.play();
}
stopBGM(fadeOut = 0) {
if (!this.bgm) return;
if (fadeOut > 0) {
this.scene.tweens.add({
targets: this.bgm,
volume: 0,
duration: fadeOut,
onComplete: () => {
this.bgm.stop();
this.bgm = null;
}
});
} else {
this.bgm.stop();
this.bgm = null;
}
}
pauseBGM() {
if (this.bgm) {
this.bgm.pause();
}
}
resumeBGM() {
if (this.bgm) {
this.bgm.resume();
}
}
playSFX(key, config = {}) {
if (this.muted) return;
return this.scene.sound.play(key, {
volume: this.sfxVolume,
...config
});
}
setSFXVolume(volume) {
this.sfxVolume = volume;
}
setBGMVolume(volume) {
this.bgmVolume = volume;
if (this.bgm) {
this.bgm.setVolume(volume);
}
}
mute() {
this.muted = true;
this.scene.sound.setMute(true);
}
unmute() {
this.muted = false;
this.scene.sound.setMute(false);
}
toggleMute() {
if (this.muted) {
this.unmute();
} else {
this.mute();
}
return this.muted;
}
}
class GameScene extends Phaser.Scene {
create() {
this.audioManager = new AudioManager(this);
this.audioManager.playBGM('background');
this.input.keyboard.on('keydown-M', () => {
this.audioManager.toggleMute();
});
}
playerJump() {
this.audioManager.playSFX('jump');
}
collectCoin() {
this.audioManager.playSFX('coin');
}
}
下一步 #
现在你已经掌握了音频系统,接下来学习 补间动画,了解如何创建更复杂的动画效果!
最后更新:2026-03-29