Cuando estuve jugando con ThreeJS para hacer un pequeño prototipo de un juego, no sabía como refrescar una escena en ThreeJS para reiniciar el nivel, cambiarlo o cargar una partida.
No es complicado pero debes saber algunos puntos.
Prerequisitos
Como sabrás, ThreeJS enlaza una escena a un elemento del DOM y sólo puedes tener 1 escena.
Probablemente tendrás una interfaz, por ejemplo con la salud del personaje:
<div id="game">
<span id="health" style="position: absolute; top: 5%; left: 5%;"></span></div>
Y tu escena lo usa como contenedor.
Vale, solo podemos tener 1 escena y ya tenemos la UI en un container. Pensemos cómo hacerlo.
Concepto
Una solución sería obtener y usar una copia del contenedor pero:
- con la interfaz
- con un ID diferente
- sin los eventos o vinculaciones de ThreeJS
- y usarlo como contenedor para la escena
Solución
En el controlador de tu juego, donde inicies la partida, añade:
$('#game').clone()
.off()
.attr('id','game_scene')
.prependTo('body');
Sí, he usado jQuery, no es obligatorio, por supuesto, puedes hacerlo con Javascript plano pero como ya lo estaba usando para alguna animación y resulta útil para el siguiente paso, pensé en reutilizarlo.
Déjame comentar cada función:
clone()
Obtiene una copia del elemento del DOMoff()
Elimina todos los eventos vinculadosattr()
Establece un ID diferenteprependTo()
Añade la copia al body del documento
Entonces, donde necesites cambiar la escena como para reiniciar el nivel, cambiarlo, cargar partida o lo que sea, añade:
$('#game_scene').remove();
var copy = $('#game').clone()
.off()
.attr('id','game_scene');
copy.prependTo('body');
Finalmente, deberías usarlo en tu escena de esta forma
var game_scene = document.getElementById('game_scene');
game_scene.appendChild(scene.renderer.domElement);
Eso es todo, te debería funcionar.
Deja un comentario si necesitas ayuda, tienes alguna pregunta o cualquier sugerencia! 🙂