3

I'm programming a game with Phaser 3 where I have a moving cart. I added a sound for the cart but it can be heard as soon as the cart is put into motion, regardless of the player's distance from it. I'd like to set the volume of the cart in a way that, if the player is very far from it, the sound will basically be muted, and that its volume will increase/decrease depending on its proximity.

I found this link and tried to apply it to my code, but with no success, so I tried to change it a little bit to see if I could make it work.

What I have in my code now is this:

preload() {
  this.load.audio("cartSound", "assets/audios/cart.mp3");
}

startCart1Movement() {
  this.startCartSound();
}

startCartSound() {
  this.distanceThreshold = 400;
  this.distanceToObject = Phaser.Math.Distance.Between(
    this.player.x, this.player.y, this.cart1.x, this.cart1.y
  );
  this.cartSound.setVolume(
    1 - (this.distanceToObject / this.distanceThreshold)
  );
  this.cartSound.play();
}

The startCartSound function is read in its entirety because if I add at the end a console.log the computer will read it, but still there is no variation in the cart sound.

Can anyone help me out? Thanks so much in advance.

Darryl Noakes
  • 2,207
  • 1
  • 9
  • 27

1 Answers1

0

Well the example should work, as long as 1 - (this.distanceToObject / this.distanceThreshold) is not negative.

Here a working example using a more or less the similar code. Just click the canvas (for the music to play) and you should hear the difference.
(maybe for you case the 400px thresshold is too small or too big, for thhe sound difference to take effect)

here a short demo:
(you can tweak the values, for velocity and maxdistance to test, the distance from where the sound is heard)

document.body.style = 'margin:0;';

var player
var soundPoint
var sound
var playing = false;

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 183,
    physics: {
        default: 'arcade',
    },
    scene: {
        preload,
        create,
        update
    },
    banner: false
}; 

function preload(){
    this.load.audio('sound', [  'https://labs.phaser.io/assets/audio/CatAstroPhi_shmup_normal.ogg',  'https://labs.phaser.io/assets/audio/CatAstroPhi_shmup_normal.mp3'
    ]);
}

function create () {
    this.add.text(10,10, 'Click to toggle Sound')
        .setScale(1.5)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
    
    this.label = this.add.text(10,40, '')
        .setScale(1)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});

    player = this.add.rectangle(20, 80, 30, 30, 0x6666ff);
    
    soundPoint = this.add.circle(config.width / 2, 50, 9,  0xff0000);
    
    this.physics.add.existing(player);
    
    player.body.setVelocity(50,0)
    
    sound = this.sound.add('sound');

    this.input.on('pointerdown', () => {
        if(!playing){
            sound.play({loop:true});
        } else {
            this.sound.stopByKey('sound');
        }
        playing = !playing;
    });
}

function update () {
    this.physics.world.wrap(player, 4);
    let maxDistance = config.width / 2.5;
    let distance = Phaser.Math.Distance.Between(soundPoint.x, soundPoint.y, player.x, player.y);
    console.info(distance)
    
    if(playing &&  sound){
        let newVolume = 1 - distance / maxDistance;
        
        // prevent negative numbers
        newVolume = Math.max(newVolume, 0);
        sound.setVolume(newVolume);
        this.label.setText(` Sound Volume: ${(newVolume * 100).toFixed(2)} %`)
    }
    
}

new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>

Important: beware that if you don't check volume might get negative. This can cause problems, you can prevent this with this line of code newVolume = Math.max(newVolume, 0);

winner_joiner
  • 12,173
  • 4
  • 36
  • 61