简体   繁体   中英

In HTML5, can I play the same sound more than once at the same time?

I'm making a game, in which sounds are often played. I noticed that a sound wont play again while it is being played. For example, the player collides with a wall, a "thump" sound is played. But, if the player collides with one wall, and then quickly collides with another wall, only one "thump" sound is played, and I believe that this happens because the first sound didn't finish. Is that true? How should I avoid this? I thought of preloading the sound three times, always playing a different copy of that sound, but this seems rather stupid...

SOLVED:

Turns out I was right... You need to preload multiple versions of the sound and then circularly play them.

THE CODE:

var ns = 3; //The number of sounds to preload. This depends on how often the sounds need to be played, but if too big it will probably cause lond loading times.
var sounds = []; //This will be a matrix of all the sounds

for (i = 0; i < ns; i ++) //We need to have ns different copies of each sound, hence:
    sounds.push([]);

for (i = 0; i < soundSources.length; i ++)
    for (j = 0; j < ns; j ++)
        sounds[j].push(new Audio(sources[i])); //Assuming that you hold your sound sauces in a "sources" array, for example ["bla.wav", "smile.dog" "scream.wav"] 

var playing = []; //This will be our play index, so we know which version has been played the last.

for (i = 0; i < soundSources.length; i ++)
    playing[i] = 0; 

playSound = function(id, vol) //id in the sounds[i] array., vol is a real number in the [0, 1] interval
{
    if (vol <= 1 && vol >= 0)
        sounds[playing[id]][id].volume = vol;
    else
        sounds[playing[id]][id].volume = 1;

    sounds[playing[id]][id].play();
    ++ playing[id]; //Each time a sound is played, increment this so the next time that sound needs to be played, we play a different version of it,

    if (playing[id] >= ns)
        playing[id] = 0;
}

You can clone the audio element. I don't know if you can play them more than once simultaneously, but here is how you can play a sound more than once without downloading it more than once.

var sound = document.getElementById("incomingMessageSound")
var sound2 = sound.cloneNode()
sound.play()
sound2.play()

I know this works for chrome, which is the only place I needed it. Good luck!

Load the sound several times to simulate polyphony. Play them in round-robin fashion. Check out my demo at matthewtoledo.com . Specifically, the function _initSoundBank()

Yes, a single <audio> object can only play one track at a time. Consider that the <audio> object has a currentTime attribute that indicates the current position of the audio track: if an <audio> object could play multiple tracks are once, what value would currentTime reflect?

See my solution for a superset of this problem on Is playing sound in Javascript performance heavy? . (Basically, add duplicate <audio> tags with the same sound.)

Although it is only implemented in FireFox and Chrome right now, in the future you should use the WebAudio API , which is specifically designed for games and audio applications in the browser.

There you can play back any sound multiple times and do several other fun stuff with it.

A good tutorial for that is here: http://www.html5rocks.com/en/tutorials/webaudio/games/

class SoundPool {
  pool : HTMLAudioElement[] = [];
  constructor(sound:HTMLAudioElement) {
    this.pool.push(sound);
  }

  play() {
    let found = false;
    for(var i=0; i<this.pool.length; i++) {
      if( this.pool[i].paused) {
        this.pool[i].play();
        found=true;
        break;
      }
    }
    if(!found) {
      let a = this.pool[0].cloneNode() as HTMLAudioElement;
      a.play();
      this.pool.push(a);
    }

  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM