made sounds play via EventQueue and flagged vars in ResourceManager
This commit is contained in:
parent
3a57a1acab
commit
90996115f1
|
@ -55,6 +55,14 @@ export default class Map<T> implements Collection {
|
|||
Object.keys(this.map).forEach(key => func(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an item associated with a key
|
||||
* @param key The key at which to delete an item
|
||||
*/
|
||||
delete(key: string): void {
|
||||
delete this.map[key];
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.forEach(key => delete this.map[key]);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Queue from "../DataTypes/Queue";
|
||||
import EventQueue from "./EventQueue";
|
||||
import GameEvent from "./GameEvent";
|
||||
|
||||
/**
|
||||
|
@ -13,6 +14,14 @@ export default class Receiver{
|
|||
this.q = new Queue(this.MAX_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds these types of events to this receiver's queue every update.
|
||||
* @param eventTypes The types of events this receiver will be subscribed to
|
||||
*/
|
||||
subscribe(eventTypes: string | Array<string>): void {
|
||||
EventQueue.getInstance().subscribe(this, eventTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an event to the queue of this reciever
|
||||
*/
|
||||
|
|
|
@ -196,6 +196,9 @@ export default class GameLoop{
|
|||
// Update all scenes
|
||||
this.sceneManager.update(deltaT);
|
||||
|
||||
// Update all sounds
|
||||
this.audioManager.update(deltaT);
|
||||
|
||||
// Load or unload any resources if needed
|
||||
this.resourceManager.update(deltaT);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import UIElement from "./Nodes/UIElement";
|
|||
import Button from "./Nodes/UIElements/Button";
|
||||
import Layer from "./Scene/Layer";
|
||||
import SecondScene from "./SecondScene";
|
||||
import GameEvent from "./Events/GameEvent";
|
||||
|
||||
export default class MainScene extends Scene {
|
||||
|
||||
|
@ -41,8 +42,7 @@ export default class MainScene extends Scene {
|
|||
backgroundTilemap.getLayer().setAlpha(0.5);
|
||||
|
||||
// Add the music and start playing it on a loop
|
||||
let music = this.add.audio("level_music");
|
||||
music.play(true);
|
||||
this.emit("play_sound", {key: "level_music", loop: true, holdReference: true});
|
||||
|
||||
// Add the tilemap
|
||||
this.add.tilemap("platformer", OrthogonalTilemap);
|
||||
|
@ -55,10 +55,6 @@ export default class MainScene extends Scene {
|
|||
let playerSprite = this.add.sprite("player", mainLayer)
|
||||
player.setSprite(playerSprite);
|
||||
|
||||
// TODO - Should sound playing be handled with events?
|
||||
let playerJumpSound = this.add.audio("player_jump");
|
||||
player.jumpSound = playerJumpSound;
|
||||
|
||||
this.viewport.follow(player);
|
||||
|
||||
// Initialize UI
|
||||
|
@ -127,7 +123,7 @@ export default class MainScene extends Scene {
|
|||
switchButton.setText("Change Scene");
|
||||
switchButton.setPosition(340, 190);
|
||||
switchButton.onClick = () => {
|
||||
music.stop();
|
||||
this.emit("stop_sound", {key: "level_music"});
|
||||
this.sceneManager.changeScene(SecondScene);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import Vec2 from "./DataTypes/Vec2";
|
|||
import Debug from "./Debug/Debug";
|
||||
import AABB from "./Physics/Colliders/AABB";
|
||||
import CanvasNode from "./Nodes/CanvasNode";
|
||||
import Audio from "./Sound/Audio";
|
||||
|
||||
export default class Player extends PhysicsNode {
|
||||
velocity: Vec2;
|
||||
|
@ -12,7 +11,6 @@ export default class Player extends PhysicsNode {
|
|||
size: Vec2;
|
||||
gravity: number = 7000;
|
||||
type: string;
|
||||
jumpSound: Audio;
|
||||
|
||||
constructor(type: string){
|
||||
super();
|
||||
|
@ -85,7 +83,7 @@ export default class Player extends PhysicsNode {
|
|||
if(this.grounded){
|
||||
if(dir.y === -1){
|
||||
// Jumping
|
||||
this.jumpSound.play();
|
||||
this.emit("play_sound", {key: "player_jump"});
|
||||
}
|
||||
vel.y = dir.y*1800;
|
||||
}
|
||||
|
|
|
@ -21,15 +21,15 @@ export default class ResourceManager {
|
|||
/**
|
||||
* Number to keep track of how many images need to be loaded
|
||||
*/
|
||||
private imagesLoaded: number;
|
||||
private loadonly_imagesLoaded: number;
|
||||
/**
|
||||
* Number to keep track of how many images are loaded
|
||||
*/
|
||||
private imagesToLoad: number;
|
||||
private loadonly_imagesToLoad: number;
|
||||
/**
|
||||
* The queue of images we must load
|
||||
*/
|
||||
private imageLoadingQueue: Queue<{key: string, path: string}>;
|
||||
private loadonly_imageLoadingQueue: Queue<{key: string, path: string}>;
|
||||
/**
|
||||
* A map of the images that are currently loaded and (presumably) being used by the scene
|
||||
*/
|
||||
|
@ -38,15 +38,15 @@ export default class ResourceManager {
|
|||
/**
|
||||
* Number to keep track of how many tilemaps need to be loaded
|
||||
*/
|
||||
private tilemapsLoaded: number;
|
||||
private loadonly_tilemapsLoaded: number;
|
||||
/**
|
||||
* Number to keep track of how many tilemaps are loaded
|
||||
*/
|
||||
private tilemapsToLoad: number;
|
||||
private loadonly_tilemapsToLoad: number;
|
||||
/**
|
||||
* The queue of tilemaps we must load
|
||||
*/
|
||||
private tilemapLoadingQueue: Queue<{key: string, path: string}>;
|
||||
private loadonly_tilemapLoadingQueue: Queue<{key: string, path: string}>;
|
||||
/**
|
||||
* A map of the tilemaps that are currently loaded and (presumably) being used by the scene
|
||||
*/
|
||||
|
@ -55,15 +55,15 @@ export default class ResourceManager {
|
|||
/**
|
||||
* Number to keep track of how many sounds need to be loaded
|
||||
*/
|
||||
private audioLoaded: number;
|
||||
private loadonly_audioLoaded: number;
|
||||
/**
|
||||
* Number to keep track of how many sounds are loaded
|
||||
*/
|
||||
private audioToLoad: number;
|
||||
private loadonly_audioToLoad: number;
|
||||
/**
|
||||
* The queue of sounds we must load
|
||||
*/
|
||||
private audioLoadingQueue: Queue<{key: string, path: string}>;
|
||||
private loadonly_audioLoadingQueue: Queue<{key: string, path: string}>;
|
||||
/**
|
||||
* A map of the sounds that are currently loaded and (presumably) being used by the scene
|
||||
*/
|
||||
|
@ -72,25 +72,25 @@ export default class ResourceManager {
|
|||
/**
|
||||
* The total number of "types" of things that need to be loaded (i.e. images and tilemaps)
|
||||
*/
|
||||
private typesToLoad: number;
|
||||
private loadonly_typesToLoad: number;
|
||||
|
||||
private constructor(){
|
||||
this.loading = false;
|
||||
this.justLoaded = false;
|
||||
|
||||
this.imagesLoaded = 0;
|
||||
this.imagesToLoad = 0;
|
||||
this.imageLoadingQueue = new Queue();
|
||||
this.loadonly_imagesLoaded = 0;
|
||||
this.loadonly_imagesToLoad = 0;
|
||||
this.loadonly_imageLoadingQueue = new Queue();
|
||||
this.images = new Map();
|
||||
|
||||
this.tilemapsLoaded = 0;
|
||||
this.tilemapsToLoad = 0;
|
||||
this.tilemapLoadingQueue = new Queue();
|
||||
this.loadonly_tilemapsLoaded = 0;
|
||||
this.loadonly_tilemapsToLoad = 0;
|
||||
this.loadonly_tilemapLoadingQueue = new Queue();
|
||||
this.tilemaps = new Map();
|
||||
|
||||
this.audioLoaded = 0;
|
||||
this.audioToLoad = 0;
|
||||
this.audioLoadingQueue = new Queue();
|
||||
this.loadonly_audioLoaded = 0;
|
||||
this.loadonly_audioToLoad = 0;
|
||||
this.loadonly_audioLoadingQueue = new Queue();
|
||||
this.audioBuffers = new Map();
|
||||
};
|
||||
|
||||
|
@ -111,7 +111,7 @@ export default class ResourceManager {
|
|||
* @param path The path to the image to load
|
||||
*/
|
||||
public image(key: string, path: string): void {
|
||||
this.imageLoadingQueue.enqueue({key: key, path: path});
|
||||
this.loadonly_imageLoadingQueue.enqueue({key: key, path: path});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,7 +132,7 @@ export default class ResourceManager {
|
|||
* @param path
|
||||
*/
|
||||
public audio(key: string, path: string): void {
|
||||
this.audioLoadingQueue.enqueue({key: key, path: path});
|
||||
this.loadonly_audioLoadingQueue.enqueue({key: key, path: path});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,7 +149,7 @@ export default class ResourceManager {
|
|||
* @param path
|
||||
*/
|
||||
public tilemap(key: string, path: string): void {
|
||||
this.tilemapLoadingQueue.enqueue({key: key, path: path});
|
||||
this.loadonly_tilemapLoadingQueue.enqueue({key: key, path: path});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,7 +166,7 @@ export default class ResourceManager {
|
|||
* @param callback
|
||||
*/
|
||||
loadResourcesFromQueue(callback: Function): void {
|
||||
this.typesToLoad = 3;
|
||||
this.loadonly_typesToLoad = 3;
|
||||
|
||||
this.loading = true;
|
||||
|
||||
|
@ -191,16 +191,16 @@ export default class ResourceManager {
|
|||
this.loading = false;
|
||||
this.justLoaded = false;
|
||||
|
||||
this.imagesLoaded = 0;
|
||||
this.imagesToLoad = 0;
|
||||
this.loadonly_imagesLoaded = 0;
|
||||
this.loadonly_imagesToLoad = 0;
|
||||
this.images.clear();
|
||||
|
||||
this.tilemapsLoaded = 0;
|
||||
this.tilemapsToLoad = 0;
|
||||
this.loadonly_tilemapsLoaded = 0;
|
||||
this.loadonly_tilemapsToLoad = 0;
|
||||
this.tilemaps.clear();
|
||||
|
||||
this.audioLoaded = 0;
|
||||
this.audioToLoad = 0;
|
||||
this.loadonly_audioLoaded = 0;
|
||||
this.loadonly_audioToLoad = 0;
|
||||
this.audioBuffers.clear();
|
||||
}
|
||||
|
||||
|
@ -209,11 +209,11 @@ export default class ResourceManager {
|
|||
* @param onFinishLoading
|
||||
*/
|
||||
private loadTilemapsFromQueue(onFinishLoading: Function): void {
|
||||
this.tilemapsToLoad = this.tilemapLoadingQueue.getSize();
|
||||
this.tilemapsLoaded = 0;
|
||||
this.loadonly_tilemapsToLoad = this.loadonly_tilemapLoadingQueue.getSize();
|
||||
this.loadonly_tilemapsLoaded = 0;
|
||||
|
||||
while(this.tilemapLoadingQueue.hasItems()){
|
||||
let tilemap = this.tilemapLoadingQueue.dequeue();
|
||||
while(this.loadonly_tilemapLoadingQueue.hasItems()){
|
||||
let tilemap = this.loadonly_tilemapLoadingQueue.dequeue();
|
||||
this.loadTilemap(tilemap.key, tilemap.path, onFinishLoading);
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ export default class ResourceManager {
|
|||
for(let tileset of tilemapObject.tilesets){
|
||||
let key = tileset.image;
|
||||
let path = StringUtils.getPathFromFilePath(pathToTilemapJSON) + key;
|
||||
this.imageLoadingQueue.enqueue({key: key, path: path});
|
||||
this.loadonly_imageLoadingQueue.enqueue({key: key, path: path});
|
||||
}
|
||||
|
||||
// Finish loading
|
||||
|
@ -248,9 +248,9 @@ export default class ResourceManager {
|
|||
* @param callback
|
||||
*/
|
||||
private finishLoadingTilemap(callback: Function): void {
|
||||
this.tilemapsLoaded += 1;
|
||||
this.loadonly_tilemapsLoaded += 1;
|
||||
|
||||
if(this.tilemapsLoaded === this.tilemapsToLoad){
|
||||
if(this.loadonly_tilemapsLoaded === this.loadonly_tilemapsToLoad){
|
||||
// We're done loading tilemaps
|
||||
callback();
|
||||
}
|
||||
|
@ -261,11 +261,11 @@ export default class ResourceManager {
|
|||
* @param onFinishLoading
|
||||
*/
|
||||
private loadImagesFromQueue(onFinishLoading: Function): void {
|
||||
this.imagesToLoad = this.imageLoadingQueue.getSize();
|
||||
this.imagesLoaded = 0;
|
||||
this.loadonly_imagesToLoad = this.loadonly_imageLoadingQueue.getSize();
|
||||
this.loadonly_imagesLoaded = 0;
|
||||
|
||||
while(this.imageLoadingQueue.hasItems()){
|
||||
let image = this.imageLoadingQueue.dequeue();
|
||||
while(this.loadonly_imageLoadingQueue.hasItems()){
|
||||
let image = this.loadonly_imageLoadingQueue.dequeue();
|
||||
this.loadImage(image.key, image.path, onFinishLoading);
|
||||
}
|
||||
}
|
||||
|
@ -295,9 +295,9 @@ export default class ResourceManager {
|
|||
* @param callback
|
||||
*/
|
||||
private finishLoadingImage(callback: Function): void {
|
||||
this.imagesLoaded += 1;
|
||||
this.loadonly_imagesLoaded += 1;
|
||||
|
||||
if(this.imagesLoaded === this.imagesToLoad ){
|
||||
if(this.loadonly_imagesLoaded === this.loadonly_imagesToLoad ){
|
||||
// We're done loading images
|
||||
callback();
|
||||
}
|
||||
|
@ -308,11 +308,11 @@ export default class ResourceManager {
|
|||
* @param onFinishLoading
|
||||
*/
|
||||
private loadAudioFromQueue(onFinishLoading: Function){
|
||||
this.audioToLoad = this.audioLoadingQueue.getSize();
|
||||
this.audioLoaded = 0;
|
||||
this.loadonly_audioToLoad = this.loadonly_audioLoadingQueue.getSize();
|
||||
this.loadonly_audioLoaded = 0;
|
||||
|
||||
while(this.audioLoadingQueue.hasItems()){
|
||||
let audio = this.audioLoadingQueue.dequeue();
|
||||
while(this.loadonly_audioLoadingQueue.hasItems()){
|
||||
let audio = this.loadonly_audioLoadingQueue.dequeue();
|
||||
this.loadAudio(audio.key, audio.path, onFinishLoading);
|
||||
}
|
||||
}
|
||||
|
@ -349,9 +349,9 @@ export default class ResourceManager {
|
|||
* @param callback
|
||||
*/
|
||||
private finishLoadingAudio(callback: Function): void {
|
||||
this.audioLoaded += 1;
|
||||
this.loadonly_audioLoaded += 1;
|
||||
|
||||
if(this.audioLoaded === this.audioToLoad){
|
||||
if(this.loadonly_audioLoaded === this.loadonly_audioToLoad){
|
||||
// We're done loading audio
|
||||
callback();
|
||||
}
|
||||
|
@ -370,10 +370,10 @@ export default class ResourceManager {
|
|||
}
|
||||
|
||||
private getLoadPercent(): number {
|
||||
return (this.tilemapsLoaded/this.tilemapsToLoad
|
||||
+ this.imagesLoaded/this.imagesToLoad
|
||||
+ this.audioLoaded/this.audioToLoad)
|
||||
/ this.typesToLoad;
|
||||
return (this.loadonly_tilemapsLoaded/this.loadonly_tilemapsToLoad
|
||||
+ this.loadonly_imagesLoaded/this.loadonly_imagesToLoad
|
||||
+ this.loadonly_audioLoaded/this.loadonly_audioToLoad)
|
||||
/ this.loadonly_typesToLoad;
|
||||
}
|
||||
|
||||
public update(deltaT: number): void {
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
import ResourceManager from "../../ResourceManager/ResourceManager";
|
||||
import AudioManager from "../../Sound/AudioManager";
|
||||
import Scene from "../Scene";
|
||||
import Audio from "../../Sound/Audio";
|
||||
|
||||
export default class AudioFactory {
|
||||
private scene: Scene;
|
||||
private resourceManager: ResourceManager;
|
||||
private audioManager: AudioManager;
|
||||
|
||||
init(scene: Scene){
|
||||
this.scene = scene;
|
||||
this.resourceManager = ResourceManager.getInstance();
|
||||
this.audioManager = AudioManager.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an audio element created using the previously loaded audio file specified by the key.
|
||||
* @param key The key of the loaded audio file
|
||||
*/
|
||||
addAudio = (key: string): Audio => {
|
||||
let audio = new Audio(key);
|
||||
return audio;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ import Scene from "../Scene";
|
|||
import PhysicsNodeFactory from "./PhysicsNodeFactory";
|
||||
import CanvasNodeFactory from "./CanvasNodeFactory";
|
||||
import TilemapFactory from "./TilemapFactory";
|
||||
import AudioFactory from "./AudioFactory";
|
||||
import PhysicsManager from "../../Physics/PhysicsManager";
|
||||
import SceneGraph from "../../SceneGraph/SceneGraph";
|
||||
import Tilemap from "../../Nodes/Tilemap";
|
||||
|
@ -13,13 +12,11 @@ export default class FactoryManager {
|
|||
private canvasNodeFactory: CanvasNodeFactory = new CanvasNodeFactory();
|
||||
private physicsNodeFactory: PhysicsNodeFactory = new PhysicsNodeFactory();
|
||||
private tilemapFactory: TilemapFactory = new TilemapFactory();
|
||||
private audioFactory: AudioFactory = new AudioFactory();
|
||||
|
||||
constructor(scene: Scene, sceneGraph: SceneGraph, physicsManager: PhysicsManager, tilemaps: Array<Tilemap>){
|
||||
this.canvasNodeFactory.init(scene, sceneGraph);
|
||||
this.physicsNodeFactory.init(scene, physicsManager);
|
||||
this.tilemapFactory.init(scene, tilemaps, physicsManager);
|
||||
this.audioFactory.init(scene);
|
||||
}
|
||||
|
||||
// Expose all of the factories through the factory manager
|
||||
|
@ -28,5 +25,4 @@ export default class FactoryManager {
|
|||
graphic = this.canvasNodeFactory.addGraphic;
|
||||
physics = this.physicsNodeFactory.add;
|
||||
tilemap = this.tilemapFactory.add;
|
||||
audio = this.audioFactory.addAudio;
|
||||
}
|
|
@ -10,6 +10,9 @@ import Tilemap from "../Nodes/Tilemap";
|
|||
import ResourceManager from "../ResourceManager/ResourceManager";
|
||||
import GameLoop from "../Loop/GameLoop";
|
||||
import SceneManager from "./SceneManager";
|
||||
import EventQueue from "../Events/EventQueue";
|
||||
import GameEvent from "../Events/GameEvent";
|
||||
import Map from "../DataTypes/Map";
|
||||
|
||||
export default class Scene{
|
||||
protected layers: Stack<Layer>;
|
||||
|
@ -143,4 +146,14 @@ export default class Scene{
|
|||
getViewport(): Viewport {
|
||||
return this.viewport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit and event of type eventType with the data packet data
|
||||
* @param eventType
|
||||
* @param data
|
||||
*/
|
||||
emit(eventType: string, data: Map<any> | Record<string, any> = null): void {
|
||||
let event = new GameEvent(eventType, data);
|
||||
EventQueue.getInstance().addEvent(event);
|
||||
}
|
||||
}
|
|
@ -40,7 +40,7 @@ export default class SecondScene extends Scene {
|
|||
backgroundTilemap.getLayer().setAlpha(0.2);
|
||||
|
||||
// Add the music and start playing it on a loop
|
||||
this.add.audio("level_music").play(true);
|
||||
this.emit("play_sound", {key: "level_music", loop: true, holdReference: true});
|
||||
|
||||
// Add the tilemap
|
||||
this.add.tilemap("level2", OrthogonalTilemap);
|
||||
|
@ -53,10 +53,6 @@ export default class SecondScene extends Scene {
|
|||
let playerSprite = this.add.sprite("player", mainLayer);
|
||||
player.setSprite(playerSprite);
|
||||
|
||||
// TODO - Should sound playing be handled with events?
|
||||
let playerJumpSound = this.add.audio("player_jump");
|
||||
player.jumpSound = playerJumpSound;
|
||||
|
||||
this.viewport.follow(player);
|
||||
|
||||
// Initialize UI
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
import AudioManager from "./AudioManager";
|
||||
|
||||
export default class Audio {
|
||||
private key: string;
|
||||
private sound: AudioBufferSourceNode;
|
||||
|
||||
constructor(key: string){
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the sound this audio represents
|
||||
* @param loop A boolean for whether or not to loop the sound
|
||||
*/
|
||||
play(loop?: boolean): void {
|
||||
this.sound = AudioManager.getInstance().createSound(this.key);
|
||||
|
||||
if(loop){
|
||||
this.sound.loop = true;
|
||||
}
|
||||
|
||||
this.sound.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the sound this audio represents
|
||||
*/
|
||||
stop(): void {
|
||||
if(this.sound){
|
||||
this.sound.stop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,19 @@
|
|||
import Map from "../DataTypes/Map";
|
||||
import Receiver from "../Events/Receiver";
|
||||
import ResourceManager from "../ResourceManager/ResourceManager";
|
||||
|
||||
export default class AudioManager {
|
||||
private static instance: AudioManager;
|
||||
private receiver: Receiver;
|
||||
private currentSounds: Map<AudioBufferSourceNode>;
|
||||
|
||||
private audioCtx: AudioContext;
|
||||
|
||||
private constructor(){
|
||||
this.initAudio();
|
||||
this.receiver = new Receiver();
|
||||
this.receiver.subscribe(["play_sound", "stop_sound"]);
|
||||
this.currentSounds = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,7 +50,17 @@ export default class AudioManager {
|
|||
* Creates a new sound from the key of a loaded audio file
|
||||
* @param key The key of the loaded audio file to create a new sound for
|
||||
*/
|
||||
createSound(key: string): AudioBufferSourceNode {
|
||||
/*
|
||||
According to the MDN, create a new sound for every call:
|
||||
|
||||
An AudioBufferSourceNode can only be played once; after each call to start(), you have to create a new node
|
||||
if you want to play the same sound again. Fortunately, these nodes are very inexpensive to create, and the
|
||||
actual AudioBuffers can be reused for multiple plays of the sound. Indeed, you can use these nodes in a
|
||||
"fire and forget" manner: create the node, call start() to begin playing the sound, and don't even bother to
|
||||
hold a reference to it. It will automatically be garbage-collected at an appropriate time, which won't be
|
||||
until sometime after the sound has finished playing.
|
||||
*/
|
||||
protected createSound(key: string): AudioBufferSourceNode {
|
||||
// Get audio buffer
|
||||
let buffer = ResourceManager.getInstance().getAudio(key);
|
||||
|
||||
|
@ -59,4 +76,58 @@ export default class AudioManager {
|
|||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the sound specified by the key
|
||||
* @param key The key of the sound to play
|
||||
* @param loop A boolean for whether or not to loop the sound
|
||||
* @param holdReference A boolean for whether or not we want to hold on to a reference of the audio node. This is good for playing music on a loop that will eventually need to be stopped.
|
||||
*/
|
||||
protected playSound(key: string, loop: boolean, holdReference: boolean): void {
|
||||
let sound = this.createSound(key);
|
||||
|
||||
if(loop){
|
||||
sound.loop = true;
|
||||
}
|
||||
|
||||
// Add a reference of the new sound to a map. This will allow us to stop a looping or long sound at a later time
|
||||
if(holdReference){
|
||||
this.currentSounds.add(key, sound);
|
||||
}
|
||||
|
||||
sound.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the sound specified by the key
|
||||
*/
|
||||
protected stopSound(key: string): void {
|
||||
let sound = this.currentSounds.get(key);
|
||||
if(sound){
|
||||
sound.stop();
|
||||
this.currentSounds.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the AudioManager
|
||||
* @param deltaT
|
||||
*/
|
||||
update(deltaT: number): void {
|
||||
// Play each audio clip requested
|
||||
// TODO - Add logic to merge sounds if there are multiple of the same key
|
||||
while(this.receiver.hasNextEvent()){
|
||||
let event = this.receiver.getNextEvent();
|
||||
if(event.type === "play_sound"){
|
||||
let soundKey = event.data.get("key");
|
||||
let loop = event.data.get("loop");
|
||||
let holdReference = event.data.get("holdReference");
|
||||
this.playSound(soundKey, loop, holdReference);
|
||||
}
|
||||
|
||||
if(event.type === "stop_sound"){
|
||||
let soundKey = event.data.get("key");
|
||||
this.stopSound(soundKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user