BabylonJS - Tocando sons e músicas

Sem som e música, um jogo está incompleto. O mecanismo de som BabylonJS vem com uma API que ajuda a adicionar efeitos sonoros ao jogo. Quando há uma luta vista no jogo, você precisa obter o tiro, o mesmo pode ser feito aqui com o motor de som de babylonjs. Você pode obter o efeito de som baseado no efeito dos controles do teclado / mouse para os jogos. O motor de som oferece som ambiente, som especializado e som direcional. O mecanismo oferece suporte aos formatos de som .mp3 e .wav.

Sintaxe

var music = new BABYLON.Sound(
   "Music", "sound.wav", scene, null, { 
      loop: true, 
      autoplay: true 
   }
);

Parâmetros

Considere os seguintes parâmetros relacionados ao motor de som -

  • Name - Nome do som.

  • URL - url do som a ser reproduzido.

  • Scene - Cena em que o som deve ser reproduzido.

  • Callbackfunction- A função de retorno de chamada que é chamada quando o som está pronto para ser reproduzido. No momento, é nula. Veremos alguns exemplos e aprenderemos como usá-lo.

  • Json object - Este objeto contém detalhes básicos do que precisa ser feito.

  • sound.autoplay - Com isso, o som é reproduzido automaticamente assim que o arquivo é baixado.

  • loop:true - Isso significa que o som será reproduzido continuamente em um loop.

Crie uma pasta de som no diretório do projeto e baixe qualquer arquivo de áudio de amostra para testar a saída.

Vamos agora adicionar som à cena que já criamos.

Demo

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Scene- Playing sounds and music</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);
            
            var music = new BABYLON.Sound("sound", "sounds/scooby.wav", scene, null, { 
               loop: true, 
               autoplay: true 
            });	
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Resultado

A linha de código acima gera a seguinte saída -

Vamos agora verificar como o callbackfunção funciona. Se você não deseja que o som seja reproduzido automaticamente ou deseja reproduzi-lo apenas quando quiser, pode fazer isso com a função de retorno de chamada.

Por exemplo,

Var music = new BABYLON.Sound ("Music", "music.wav", scene, function callback() {music.play();});

Demo

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Scene- Playing sounds and music</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true)
            
            var music = new BABYLON.Sound(
               "sound", "sounds/scooby.wav", scene, function callback() { setTimeout(function() {music.play();}, 5000)});	
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

No retorno de chamada, usaremos setTimeout. Isso significa que queremos que o som seja reproduzido somente após um determinado tempo. Adicionamos 5s como um cronômetro a ele, para que o som seja reproduzido quando os arquivos Scooby.wav forem baixados e 5s forem concluídos.

Tocar sons com cliques e teclas do teclado

Ao clicar em qualquer lugar da cena, você ouvirá o efeito sonoro explosivo e se pressionar qualquer uma das teclas de seta -esquerda, direita, para cima ou para baixo, o efeito sonoro explosivo será reproduzido.

Para clicar, estamos anexando o evento onmousedownpara a janela e para as chaves, usaremos o evento keydown. Com base no código de tecla, o som é reproduzido.

Demo

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Scene- Playing sounds and music</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true)
            
            var sound = new BABYLON.Sound("gunshot", "sounds/explosion.wav", scene);

            window.addEventListener("mousedown", function (evt) {	
               if (evt.button === 0) { // onclick
                  sound.play();
               }
            });

            window.addEventListener("keydown", function (evt) { // arrow key left right up down
               if (evt.keyCode === 37 || evt.keyCode === 38 || evt.keyCode === 39 || evt.keyCode === 40) {
                  sound.play();
               }
            });		
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Resultado

A linha de código acima irá gerar a seguinte saída -

Você pode controlar o volume do som no objeto json, que encontramos no início.

Por exemplo,

Var music = new BABYLON.Sound("sound", "sounds/scooby.wav", scene, null, { 
   loop: true, 
   autoplay: true, 
   volume:0.5 
});

Para saber quando um arquivo de som terminou, há um evento que pode ser usado da seguinte maneira -

music.onended = function () {	
   console.log("sound ended");
   
   //you can do the required stuff here like play it again or play some other sound etc.
};

A propriedade SetVolume também está disponível caso você queira controlar o som além do construtor.

Por exemplo,

music.setVolume(volume);

Se você estiver reproduzindo mais de um som em sua cena, poderá definir um som global para todos os sons criados.

Por exemplo,

BABYLON.Engine.audioEngine.setGlobalVolume(0.5);

Criação de um som 3D espacial

Se você deseja converter o som em som espacial (som semelhante ao som espacial), é necessário adicionar opções ao seu construtor de som.

Por exemplo,

var music = new BABYLON.Sound("music", "sounds/explosion.wav", scene, null, { 
   loop: false, 
   autoplay: true, 
   spatialSound: true 
});

A seguir estão as diferentes opções para som espacial -

  • DistanceModel- Está usando uma equação “linear” por padrão. Outras opções são “inversa” ou “exponencial”.

  • MaxDistance - Está definido como 100. Isso significa que quando o ouvinte estiver a mais de 100 unidades do som, o volume será 0. Você não pode mais ouvir o som

  • PanningModel- Está definido para “HRTF”. A especificação diz que é um algoritmo de espacialização de qualidade superior usando uma convolução com respostas de impulso medidas de seres humanos. Refere-se à saída estéreo.

  • MaxDistance - É usado apenas quando distanceModel é linear. Não é usado com inverso ou exponencial.

Demonstração com som espacial

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Scene- Playing sounds and music</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);	
            
            var music = new BABYLON.Sound(
               "music", "sounds/explosion.wav", scene, null, {
                  loop: false, autoplay: true, spatialSound: true, distanceModel: "exponential"
               }
            );
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Anexando som a uma malha

Usando BABYLON.Sound, você pode anexar som à sua malha. Se a malha estiver se movendo, o som se moverá junto com ela.AttachtoMesh (mesh) é o método a ser usado.

Demo

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Scene- Playing sounds and music</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);

            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var materialforbox = new BABYLON.StandardMaterial("texture1", scene);
            var box = BABYLON.Mesh.CreateBox("box", '2', scene);	
            box.material  = materialforbox;
            materialforbox.ambientColor = new BABYLON.Color3(1, 0, 0.2);

            var music = new BABYLON.Sound("music", "sounds/explosion.wav", scene, null, { 
               loop: false, 
               autoplay: true, 
               spatialSound: true, 
               distanceModel: "exponential"
            });	
            music.attachToMesh(box);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

Resultado

A linha de código acima gera a seguinte saída -