How to use ecs.Audio?

Hello,

I have some questions regarding ecs.Audio please.

(1)

I have an entity called GameOverScreen with a custom component responsible for playing game-over audio when certain conditions are met. If the game over happens quickly after starting the game, the audio plays as expected. However, if it takes some time before the game over occurs, the audio doesn’t play. I’m not sure why or if there is anything I should check which could be the source of this problem?

Here’s my code:

In the Game Over custom component’s add method, I create an audio element:

  add: (world, component) => {
    const {eid, schema: {landingScreenId, gameManagerId}} = component

    ecs.Audio.set(world, eid, {
      url: gameOverAudioSrc,
      loop: false,
      paused: true, // not playing by default
    })

...

const handleGameOver = () => {
 const audioGameOver = ecs.Audio.cursor(world, eid)
 audioGameOver.paused = false
}
 world.events.addListener(eid, 'game-over', handleGameOver)

Initially, I tried creating the audio component inside the handleGameOver callback using ecs.Audio.set, but I faced the same issue. So I’m testing alternatives where I set it to paused: true by default and unpause it later.

I even tried to set the volume to 0 initially with pause: false but the audio starts and I can hear it, it’s like volume 0 is not working.

I also tried changing pause to true with an ecs.Audio.acquire and ecs.Audio.commit but I still have the same issue.

const handleGameOver() => {
...
     ecs.Audio.set(world, eid, {
        url: gameOverAudioSrc,
        loop: false,
        paused: false,
        // volume: 0,
      })
}

(2)

Ideally, I would like to set the audio component directly on the entity from the Studio UI and by code play it when the ‘game-over’ event is triggered, but I haven’t figured out how to do this yet. Although I think in some use case it’s interesting to understand how to do it by code.

Thank you.

1 Like

I used the same Audio controller logic as in the studio-dragon-dash project:

// Helper functions for controlling audio components
import * as ecs from '@8thwall/ecs'  // This is how you access the ecs library

// Given an entity id, play its audio component
const PlayAudio = (world, componentEID) => {
  if (ecs.Audio.has(world, componentEID)) {  // If the supplied entity has an Audio component...
    const audio = ecs.Audio.cursor(world, componentEID)  // Get a reference to that Audio component
    audio.autoPlay = true  // And play the assigned audio source  // And play the assigned audio source
  }
}

// Given an entity id, pause its audio component if it is playing
const PauseAudio = (world, componentEID) => {
  if (ecs.Audio.has(world, componentEID)) {
    const audio = ecs.Audio.cursor(world, componentEID)
    audio.paused = true
  }
}

// Given an entity id with an audio component, change its audio source
const ChangeAudio = (world, componentEID, newAudio) => {
  if (ecs.Audio.has(world, componentEID)) {
    const audio = ecs.Audio.cursor(world, componentEID)
    audio.url = newAudio
  }
}

export {PauseAudio, PlayAudio, ChangeAudio}

However, I still have the issue where most of the time, when I call PlayAudio by code, the audio does not play.

I’ve noticed two things:

  • If I set autoPlay to true in the Audio component by default, then when I call PlayAudio at some point in the code, the audio will play. If autoPlay is false, most of the time PlayAudio won’t work in my project.

  • I thought I could set the volume to 0 by default on the Audio component, so that when autoPlay happens on start, I won’t hear the audio, and then in PlayAudio I can set audio.volume = 1. But setting the volume to 0 by default is not working from the Audio component in my project; I can still hear the audio.

Have you checked the console? It could the the browser is blocking audio playback because there’s no user gesture detected.

Hi GeorgeButler thank you for your answer, there is no error, warnings or anything showing in the console when I’m playing the Audio.

To give you more details, in my game the user moves around a character with his finger to collect coins. There are 4 Audios file: background / game over / game win / coin collection.

If I start the game and trigger the Game Over state quickly enough without collecting any coins the Game Over Audio track is playing 100% of the time. If I collect coins and move around and then trigger the Game Over state, the Audio won’t play. Same behaviour for my Win Screen Audio.

I also have the Background Audio looping which is working, and the Audio when collecting a coin which is working “most of the time”. If this Coin Audio is not working for some reason, I can refresh the page and it will play the audio.

Got it, I’ll take a look at this and see if I figure out what could be causing the issue.

1 Like