UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

264 lines (261 loc) 6.41 kB
import { DISTANCE_LINEAR } from '../../../platform/sound/constants.js'; import { Component } from '../component.js'; import { SoundSlot } from './slot.js'; class SoundComponent extends Component { static{ this.EVENT_PLAY = 'play'; } static{ this.EVENT_PAUSE = 'pause'; } static{ this.EVENT_RESUME = 'resume'; } static{ this.EVENT_STOP = 'stop'; } static{ this.EVENT_END = 'end'; } _updateSoundInstances(property, value, isFactor) { const slots = this._slots; for(const key in slots){ const slot = slots[key]; if (!slot.overlap) { const instances = slot.instances; for(let i = 0, len = instances.length; i < len; i++){ instances[i][property] = isFactor ? slot[property] * value : value; } } } } set distanceModel(value) { this._distanceModel = value; this._updateSoundInstances('distanceModel', value, false); } get distanceModel() { return this._distanceModel; } set maxDistance(value) { this._maxDistance = value; this._updateSoundInstances('maxDistance', value, false); } get maxDistance() { return this._maxDistance; } set refDistance(value) { this._refDistance = value; this._updateSoundInstances('refDistance', value, false); } get refDistance() { return this._refDistance; } set rollOffFactor(value) { this._rollOffFactor = value; this._updateSoundInstances('rollOffFactor', value, false); } get rollOffFactor() { return this._rollOffFactor; } set pitch(value) { this._pitch = value; this._updateSoundInstances('pitch', value, true); } get pitch() { return this._pitch; } set volume(value) { this._volume = value; this._updateSoundInstances('volume', value, true); } get volume() { return this._volume; } set positional(newValue) { this._positional = newValue; const slots = this._slots; for(const key in slots){ const slot = slots[key]; if (!slot.overlap) { const instances = slot.instances; const oldLength = instances.length; for(let i = oldLength - 1; i >= 0; i--){ const isPlaying = instances[i].isPlaying || instances[i].isSuspended; const currentTime = instances[i].currentTime; if (isPlaying) { instances[i].stop(); } const instance = slot._createInstance(); if (isPlaying) { instance.play(); instance.currentTime = currentTime; } instances.push(instance); } } } } get positional() { return this._positional; } set slots(newValue) { const oldValue = this._slots; if (oldValue) { for(const key in oldValue){ oldValue[key].stop(); } } const slots = {}; for(const key in newValue){ if (!(newValue[key] instanceof SoundSlot)) { if (newValue[key].name) { slots[newValue[key].name] = new SoundSlot(this, newValue[key].name, newValue[key]); } } else { slots[newValue[key].name] = newValue[key]; } } this._slots = slots; if (this.enabled && this.entity.enabled) { this.onEnable(); } } get slots() { return this._slots; } onEnable() { if (this.system._inTools) { return; } const slots = this._slots; const playingBeforeDisable = this._playingBeforeDisable; for(const key in slots){ const slot = slots[key]; if (slot.autoPlay && slot.isStopped) { slot.play(); } else if (playingBeforeDisable[key]) { slot.resume(); } else if (!slot.isLoaded) { slot.load(); } } } onDisable() { const slots = this._slots; const playingBeforeDisable = {}; for(const key in slots){ if (!slots[key].overlap) { if (slots[key].isPlaying) { slots[key].pause(); playingBeforeDisable[key] = true; } } } this._playingBeforeDisable = playingBeforeDisable; } onRemove() { this.off(); } addSlot(name, options) { const slots = this._slots; if (slots[name]) { return null; } const slot = new SoundSlot(this, name, options); slots[name] = slot; if (slot.autoPlay && this.enabled && this.entity.enabled) { slot.play(); } return slot; } removeSlot(name) { const slots = this._slots; if (slots[name]) { slots[name].stop(); delete slots[name]; } } slot(name) { return this._slots[name]; } _getSlotProperty(name, property) { if (!this.enabled || !this.entity.enabled) { return undefined; } const slot = this._slots[name]; if (!slot) { return undefined; } return slot[property]; } isPlaying(name) { return this._getSlotProperty(name, 'isPlaying') || false; } isLoaded(name) { return this._getSlotProperty(name, 'isLoaded') || false; } isPaused(name) { return this._getSlotProperty(name, 'isPaused') || false; } isStopped(name) { return this._getSlotProperty(name, 'isStopped') || false; } play(name) { if (!this.enabled || !this.entity.enabled) { return null; } const slot = this._slots[name]; if (!slot) { return null; } return slot.play(); } pause(name) { const slots = this._slots; if (name) { const slot = slots[name]; if (!slot) { return; } slot.pause(); } else { for(const key in slots){ slots[key].pause(); } } } resume(name) { const slots = this._slots; if (name) { const slot = slots[name]; if (!slot) { return; } if (slot.isPaused) { slot.resume(); } } else { for(const key in slots){ slots[key].resume(); } } } stop(name) { const slots = this._slots; if (name) { const slot = slots[name]; if (!slot) { return; } slot.stop(); } else { for(const key in slots){ slots[key].stop(); } } } constructor(...args){ super(...args), this._volume = 1, this._pitch = 1, this._positional = true, this._refDistance = 1, this._maxDistance = 10000, this._rollOffFactor = 1, this._distanceModel = DISTANCE_LINEAR, this._slots = {}, this._playingBeforeDisable = {}; } } export { SoundComponent };