Sound Manager

This commit is contained in:
MyNameIsBatman 2021-07-04 01:24:09 -03:00
parent 2735af953d
commit 89f13aeb89
3 changed files with 240 additions and 0 deletions

View File

@ -1,4 +1,5 @@
import { Application, SCALE_MODES, settings } from 'pixi.js'; import { Application, SCALE_MODES, settings } from 'pixi.js';
import { INitroManager } from '..';
import { ConfigurationEvent } from '../core/configuration/ConfigurationEvent'; import { ConfigurationEvent } from '../core/configuration/ConfigurationEvent';
import { EventDispatcher } from '../core/events/EventDispatcher'; import { EventDispatcher } from '../core/events/EventDispatcher';
import { IEventDispatcher } from '../core/events/IEventDispatcher'; import { IEventDispatcher } from '../core/events/IEventDispatcher';
@ -28,6 +29,7 @@ import { IRoomSessionManager } from './session/IRoomSessionManager';
import { ISessionDataManager } from './session/ISessionDataManager'; import { ISessionDataManager } from './session/ISessionDataManager';
import { RoomSessionManager } from './session/RoomSessionManager'; import { RoomSessionManager } from './session/RoomSessionManager';
import { SessionDataManager } from './session/SessionDataManager'; import { SessionDataManager } from './session/SessionDataManager';
import { SoundManager } from './sound/SoundManager';
import { HabboWebTools } from './utils/HabboWebTools'; import { HabboWebTools } from './utils/HabboWebTools';
LegacyExternalInterface.available; LegacyExternalInterface.available;
@ -57,6 +59,7 @@ export class Nitro extends Application implements INitro
private _roomSessionManager: IRoomSessionManager; private _roomSessionManager: IRoomSessionManager;
private _roomManager: IRoomManager; private _roomManager: IRoomManager;
private _cameraManager: IRoomCameraWidgetManager; private _cameraManager: IRoomCameraWidgetManager;
private _soundManager: INitroManager;
private _linkTrackers: ILinkEventTracker[]; private _linkTrackers: ILinkEventTracker[];
private _workerTrackers: IWorkerEventTracker[]; private _workerTrackers: IWorkerEventTracker[];
@ -98,6 +101,7 @@ export class Nitro extends Application implements INitro
this._roomSessionManager = new RoomSessionManager(this._communication, this._roomEngine); this._roomSessionManager = new RoomSessionManager(this._communication, this._roomEngine);
this._roomManager = new RoomManager(this._roomEngine, this._roomEngine.visualizationFactory, this._roomEngine.logicFactory); this._roomManager = new RoomManager(this._roomEngine, this._roomEngine.visualizationFactory, this._roomEngine.logicFactory);
this._cameraManager = new RoomCameraWidgetManager(); this._cameraManager = new RoomCameraWidgetManager();
this._soundManager = new SoundManager();
this._linkTrackers = []; this._linkTrackers = [];
this._workerTrackers = []; this._workerTrackers = [];
@ -147,6 +151,8 @@ export class Nitro extends Application implements INitro
if(this._avatar) this._avatar.init(); if(this._avatar) this._avatar.init();
if(this._soundManager) this._soundManager.init();
if(this._roomEngine) if(this._roomEngine)
{ {
this._roomEngine.sessionDataManager = this._sessionDataManager; this._roomEngine.sessionDataManager = this._sessionDataManager;
@ -208,6 +214,13 @@ export class Nitro extends Application implements INitro
this._avatar = null; this._avatar = null;
} }
if(this._soundManager)
{
this._soundManager.dispose();
this._soundManager = null;
}
if(this._communication) if(this._communication)
{ {
this._communication.dispose(); this._communication.dispose();

View File

@ -0,0 +1,19 @@
import { NitroEvent } from '../../core/events/NitroEvent';
export class NitroSoundEvent extends NitroEvent
{
public static PLAY_SOUND: string = 'NSOE_PLAY_SOUND';
private _sampleCode: string;
constructor(type: string, sampleCode: string)
{
super(type);
this._sampleCode = sampleCode;
}
public get sampleCode(): string
{
return this._sampleCode;
}
}

View File

@ -0,0 +1,208 @@
import { AdvancedMap, Nitro, NitroSettingsEvent, RoomEngineEvent, RoomEngineObjectEvent, RoomEngineSamplePlaybackEvent } from '../..';
import { NitroManager } from '../../core/common/NitroManager';
import { NitroSoundEvent } from '../events/NitroSoundEvent';
import { NitroEvent } from './../../core/events/NitroEvent';
export class SoundManager extends NitroManager
{
private _volumeSystem: number;
private _volumeFurni: number;
private _volumeTrax: number;
private _internalSamples: AdvancedMap<string, HTMLAudioElement>;
private _furniSamples: AdvancedMap<number, HTMLAudioElement>;
private _furnitureBeingPlayed: AdvancedMap<number, number>;
constructor()
{
super();
this._volumeSystem = 0.5;
this._volumeFurni = 0.5;
this._volumeTrax = 0.5;
this._internalSamples = new AdvancedMap();
this._furniSamples = new AdvancedMap();
this._furnitureBeingPlayed = new AdvancedMap();
this.onEvent = this.onEvent.bind(this);
}
private onEvent(event: NitroEvent)
{
switch(event.type)
{
case RoomEngineSamplePlaybackEvent.PLAY_SAMPLE: {
const castedEvent = (event as RoomEngineSamplePlaybackEvent);
this.playFurniSample(castedEvent.objectId, castedEvent.sampleId, castedEvent.pitch);
return;
}
case RoomEngineObjectEvent.REMOVED: {
const castedEvent = (event as RoomEngineObjectEvent);
this.stopFurniSample(castedEvent.objectId);
return;
}
case RoomEngineEvent.DISPOSED: {
this._furnitureBeingPlayed.getKeys().forEach((objectId: number) =>
{
this.stopFurniSample(objectId);
});
return;
}
case NitroSettingsEvent.SETTINGS_UPDATED: {
const castedEvent = (event as NitroSettingsEvent);
const volumeFurniUpdated = castedEvent.volumeFurni !== this._volumeFurni;
this._volumeSystem = castedEvent.volumeSystem;
this._volumeFurni = castedEvent.volumeFurni;
this._volumeTrax = castedEvent.volumeTrax;
if(volumeFurniUpdated) this.updateFurniSamplesVolume(this._volumeFurni);
return;
}
case NitroSoundEvent.PLAY_SOUND: {
const castedEvent = (event as NitroSoundEvent);
this.playInternalSample(castedEvent.sampleCode);
return;
}
}
}
public onInit(): void
{
Nitro.instance.roomEngine.events.addEventListener(RoomEngineSamplePlaybackEvent.PLAY_SAMPLE, this.onEvent);
Nitro.instance.roomEngine.events.addEventListener(RoomEngineObjectEvent.REMOVED, this.onEvent);
Nitro.instance.roomEngine.events.addEventListener(RoomEngineEvent.DISPOSED, this.onEvent);
Nitro.instance.events.addEventListener(NitroSettingsEvent.SETTINGS_UPDATED, this.onEvent);
Nitro.instance.events.addEventListener(NitroSoundEvent.PLAY_SOUND, this.onEvent);
}
public onDispose(): void
{
Nitro.instance.roomEngine.events.removeEventListener(RoomEngineSamplePlaybackEvent.PLAY_SAMPLE, this.onEvent);
Nitro.instance.roomEngine.events.removeEventListener(RoomEngineObjectEvent.REMOVED, this.onEvent);
Nitro.instance.roomEngine.events.removeEventListener(RoomEngineEvent.DISPOSED, this.onEvent);
Nitro.instance.events.removeEventListener(NitroSettingsEvent.SETTINGS_UPDATED, this.onEvent);
Nitro.instance.events.removeEventListener(NitroSoundEvent.PLAY_SOUND, this.onEvent);
}
private playSample(sample: HTMLAudioElement, volume: number, pitch: number = 1): void
{
sample.volume = volume;
sample.currentTime = 0;
try
{
sample.play();
}
catch (e)
{
console.log(e);
}
}
private playInternalSample(code: string): void
{
let sample = this._internalSamples.getValue(code);
if(!sample)
{
const sampleUrl = Nitro.instance.getConfiguration<string>('internal.samples.url');
sample = new Audio(sampleUrl.replace('%sample%', code));
this._internalSamples.add(code, sample);
}
this.playSample(sample, this._volumeSystem);
}
private playFurniSample(objectId: number, code: number, pitch: number): void
{
let sample = this._furniSamples.getValue(code);
if(!sample)
{
const sampleUrl = Nitro.instance.getConfiguration<string>('external.samples.url');
sample = new Audio(sampleUrl.replace('%sample%', code.toString()));
this._furniSamples.add(code, sample);
}
if(!this._furnitureBeingPlayed.hasKey(objectId)) this._furnitureBeingPlayed.add(objectId, code);
sample.onended = (event) =>
{
this.stopFurniSample(objectId);
};
sample.onpause = (event) =>
{
this.stopFurniSample(objectId);
};
sample.onerror = (event) =>
{
this.stopFurniSample(objectId);
};
this.playSample(sample, this._volumeFurni, pitch);
}
private stopInternalSample(code: string): void
{
const sample = this._internalSamples.getValue(code);
if(!sample) return;
try
{
sample.pause();
}
catch (e)
{
console.log(e);
}
}
private stopFurniSample(objectId: number): void
{
const furnitureBeingPlayed = this._furnitureBeingPlayed.getValue(objectId);
if(!furnitureBeingPlayed) return;
const sample = this._furniSamples.getValue(furnitureBeingPlayed);
this._furnitureBeingPlayed.remove(objectId);
if(!sample) return;
try
{
sample.pause();
}
catch (e)
{
console.log(e);
}
}
private updateInternalSamplesVolume(volume: number): void
{
this._internalSamples.getValues().forEach((sample: HTMLAudioElement) =>
{
sample.volume = volume;
});
}
private updateFurniSamplesVolume(volume: number): void
{
this._furniSamples.getValues().forEach((sample: HTMLAudioElement) =>
{
sample.volume = volume;
});
}
}