Online Book Reader

Home Category

HTML5 Canvas [137]

By Root 6450 0
an HTMLAudioElement repeatedly, or create unlimited sound objects on the fly. However, what if we cap the number of audio objects we create, and put those objects in a pool so we can use them over and over? This will save us memory, and after the sounds are loaded, we shouldn’t see any loading pause before they are played, right?

We will implement a solution that uses HTMLAudioElement objects as general-purpose sound objects. We will keep a pool of them, and change the src attribute to whatever sound we want to play. This appears to be an elegant solution that reuses as much as possible, in addition to giving us a lot of flexibility as to which sounds we want to play.

In canvasApp(), we will create a new constant named MAX_SOUNDS. This will represent the maximum number of sound objects we can create at any one time. We will also rename our sounds array to soundPool to better describe its purpose:

const MAX_SOUNDS = 8;

var soundPool = new Array();

The big change here is the playSound() function. It uses the same parameters as the one from iteration #2, but the functionality is very different:

function playSound(sound,volume) {

The first half of the function loops through the soundPool array to see whether any of the HTMLAudioElement objects in the pool are available to play a sound. We determine this by checking the ended property. Since only HTMLAudioElement objects that have previously been used to play a sound are put into the pool, the ended property will be set to true once the sound has finished playing. By replaying sounds that have finished, we remove the issue of trying to reuse an HTMLAudioElement object to play a sound while it is already in use:

var soundFound = false;

var soundIndex = 0;

var tempSound;

if (soundPool.length> 0) {

while (!soundFound && soundIndex < soundPool.length) {

var tSound = soundPool[soundIndex];

if (tSound.ended) {

soundFound = true;

} else {

soundIndex++;

}

}

}

if (soundFound) {

tempSound = soundPool[soundIndex];

tempSound.setAttribute("src", sound + "." + audioType);

tempSound.loop = false;

tempSound.volume = volume;

tempSound.play();

If we don’t find a sound, and the size of the pool is less than MAX_SOUNDS, we go ahead and create a new HTMLAudioElement, call its play() function, and push it into the sound pool. This keeps the pool from getting too large, while making sure there are not too many HTMLAudioElement objects in the browser at any one time:

} else if (soundPool.length < MAX_SOUNDS){

tempSound = document.createElement("audio");

tempSound.setAttribute("src", sound + "." + audioType);

tempSound.volume = volume;

tempSound.play();

soundPool.push(tempSound);

}

}

You can go ahead and try this iteration by loading CH7EX8.html in your HTML5-compliant web browser. In this case, it works! You hear every sound, and the browser doesn’t die like it would with iteration #2.

Unfortunately, there are some issues. On some browsers, there is still a pause before a sound plays, just like with iteration #2. Again, this happens more often when the page is loaded from an external website than when it is loaded locally in a web browser.

The worst manifestation of this comes in Google Chrome, where the sounds pause every time they are played. Also, in Firefox, the src doesn’t change for all the objects, making the shoot sound play when the explode sound should play, and vice versa.

Uh-oh, it looks like we need another iteration. Figure 7-9 shows Space Raiders playing with a pool size governed by MAX_SOUNDS.

Figure 7-9. Space Raiders with a sound pool

Iteration #4: Reusing Preloaded Sounds


Even though the code in iteration #3 was pretty clean, it simply did not work for us. Instead, we need to compromise and implement a solution that is less elegant, but that works to play sounds nearly every time they are needed. This solution must also work both locally and when loaded from a website.

For this final iteration, we are going to use a sound pool just like in iteration #3, but it will operate in a different way. We will not reuse sound objects

Return Main Page Previous Page Next Page

®Online Book Reader