Tabla de contenidos

Introducción

WebVR es una API de JavaScript que permite a las experiencias de realidad virtual que se ejecutan en un navegador web en auriculares de realidad virtual, teléfonos móviles y tabletas y computadoras regulares. Este tutorial le dará a conocer el desarrollo WebVR mediante la creación de un juego de acción en primera persona que utiliza el marco de A-Frame. Para seguir adelante, se requieren conocimientos básicos de HTML y JavaScript.

No se pierda! extremos de la oferta en

  • Accede a los más de 200 cursos
  • Nuevos cursos añadió mensual
  • Cancelar en cualquier momento
  • Los certificados de terminación

    ACCESO ahora

    Descargas

    Los archivos de este tutorial están disponibles para su descarga aquí.

    ¿Qué es A-Frame?

    A-Frame es un framework de desarrollo web front-end para el desarrollo de WebVR. Técnicamente, A-Frame es una abstracción de three.js, una biblioteca JavaScript que utiliza la API de WebGL para rendir gráficos 3D en el navegador.

    Una aplicación A-Frame es simplemente una página web HTML que incluye la biblioteca A-Frame y contiene entidades incrustadas dentro de etiquetas. Este es el código completo para el “Hola, mundo” de A-Frame:
    Hola, WebVR! – A-Frame </ title> <meta name = "description" content = "Hola, WebVR - A-Frame"> <script src = "https://aframe.io/releases/0.7.0/aframe.min Js "> </ script> </ head> <body> <a-escena> <a-box posición =" - 1 0,5 -3" rotación = "0 45 0" color = "# 4CC3D9" sombra> </ a-box> <a-esfera posición = "0 1,25 -5" radio = "1,25" color = "# EF2D5E" sombra> </ una esfera-> <posición a-cilindro = "1 0,75 -3" radio =" 0.5" height = "1.5" color = "# FFC65D" sombra> </ a cilindros> <a-plano de posición = "0 0 -4" rotación = "- 90 0 0" width = "4" height = "4 "color =" # 7BC8A4" sombra> </ a de plano> <a-cielo color = "# ECECEC"> </ a-cielo> </ a-escena> </ body> </ html> 1234567891011121314151617 <! DOCTYPE html> <html> <head> <title> Hola, WebVR -A-Frame </ title> <meta name = "description" content = "Hola, WebVR - A-Frame!"> <script src = "https: //aframe.io/releases/0.7.0/aframe.min.js"></script></head><body><a-scene><a-box posición = "- 1 0,5 -3" rotación = "0 45 0" color = "# 4CC3D9" sombra> </ a-box> posición <a-esfera = "0 1,25 -5" radio = "1,25" color = "# EF2D5E" sombra> </ a-esfera> <a cilindros posición = "1 0,7 5 -3 "radio =" 0.5 "height =" 1.5 "color =" # FFC65D "sombra> </ a de cilindro-> <posición un plano =" 0 0 -4 "rotación =" - 90 0 0" width = "4" height = "4" color = "# 7BC8A4" sombra> </ a de plano> <a-cielo color = "# ECECEC"> </ a-cielo> </ a-escena> </ body> < / html> </p> <p> <img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x130.png" alt = "" /> </ p><br /> <P> A-Frame utiliza la arquitectura de entidad-componente. Cada objeto en A-Frame es una entidad representada como una etiqueta HTML. Componentes que se parecen a los atributos HTML añadir comportamientos a las entidades. Algunos componentes, tales como la geometría, material y posición, se construyen en A-Frame. Usted puede crear sus propios componentes personalizados en JavaScript o utilizar componentes existentes del registro A-Frame. </ P><br /> <P> entidades comunes son abstraído en primitivos, que son comparables a las casas prefabricadas en la unidad. A-cuadro, a-esfera, un cilindro, y un plano son todas las primitivas. </ P><br /> <H3> Configuración de un Proyecto </ h3><br /> <P> Desarrollar y probar en A-Frame es más fácil ifwe ejecutar un servidor web local, en lugar de utilizar el menú Archivo-> Abrir en un navegador para abrir una página. Hay varias formas de ejecutar un servidor local, pero vamos a utilizar de nodo y NPM, el gestor de paquetes de nodo. Siga las instrucciones en https://nodejs.org/en/download/ para descargar e instalar el Nodo y NPM para su sistema. </ P><br /> <P> Para configurar el proyecto, crear un directorio llamado a-fps y crear un archivo llamado un-cps / package.json con el siguiente contenido: </ p><br /> { "Name": "a-fps", "Descripción": "A-Frame Shooter en primera persona", "versión": "0.1.0", "licencia": "MIT", "scripts": { "inicio ": "budo --live --verbose --port 3000 --open"}, "devDependencies": { "budo": "^ 7.0.0"}, "palabras clave": [ "aframe", "webvr", "vr"]} 1234567891011121314151617 { "name": "a-fps", "Descripción": "a-Frame shooter en primera persona", "versión": "0.1.0", "licencia": "MIT"," scripts ": {" Inicio ":" budo --live --verbose --port 3000 --open "}," devDependencies ": {" budo ":" ^ 7.0.0 "}," palabras clave ": [" aframe ", "webvr", "VR"]} </p> <p> Ahora ejecute </ p><br /> NPM instalar </p> <p> en su terminal en el directorio de un fps. Esto instalará el paquete budo que aparece como una dependencia en package.json. Budo es un servidor web de desarrollo. Cuando se ejecuta </ ​​p><br /> NPM empezar </p> <p> en su terminal, budo se iniciará un servidor web en el puerto 3000. Prueba de sus páginas web en el directorio donde se está ejecutando el budo, vaya a http: // localhost:. 3000 en su navegador </ p><br /> <Img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x80.png" alt = "Salida de la NGP instalar." /> <Img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x56.png" alt = "Salida de inicio NPM." /> <P> Todos los depencies se instalan en el directorio node_modules. </ P><br /> <H3> Creación de una escena </ h3><br /> <P> A-Frame, escenas están encerrados en <a-escena> </ a-escena> etiquetas. Cada objeto en la escena es una entidad identificada por <a-entidad> </ a-entidad> etiquetas, con componentes añadidos como atributos del <a-entidad> etiqueta. </ P><br /> <P> establecer Empecemos nuestra escena. Crear un nuevo archivo, index.html, en el directorio de su proyecto, y abrirlo en un editor de código o IDE. Estoy utilizando código de Visual Studio -. Otras opciones incluyen Atom, Sublime Text, o vim clásico o Emacs </ p><br /> <P> Crea un archivo HTML esqueleto en index.html: </ p><br /> <! DOCTYPE html> <html> <head> <script src = "https://aframe.io/releases/0.7.0/aframe.min.js"> </ script> </ head> <body> </ body> </ html> 12345678 <! DOCTYPEhtml> <html> <head> <script src = "https://aframe.io/releases/0.7.0/aframe.min.js"> </ script> </ head > <body> </ body> </ html> </p> <p> La etiqueta script hace que la versión A-Frame 0.7.0 accesible. </ p> <P> Dentro de la sección del cuerpo, crear una escena A-Frame: </ p> <Body> <una escena> <a-activos> <img id = "skyTexture" src = "http://fymm-rpg.net/wp-content/uploads/sky.jpg" crossorigin = "Anónimo"> < / a-activos> <a-cielo src = "# skyTexture" theta-length = "90" radio = "30"> </ a-cielo> <a la cámara> <una entidad cursor = "downEvents: triggerdown; upEvents: triggerUp" geometría = "primitivo: anillo; radiusInner: 0,03; radiusOuter: color de 0,05" del material = ": blue; shader:" posición = "plana 0 0 -1"> </ a-entidad> </ a-cámara > <a-entidad id = geometría "tierra" = "primitivo: cilindro; radius: 30; altura: 0,1" posición = "0 0 0" del material = "shader: plana; color: # 424949"> </ a-entidad > </ a-escena> </ body> 1234567891011121314151617181920 <body> <una escena> <a-activos> <img id = "skyTexture" src = "http://fymm-rpg.net/wp-content/uploads /sky.jpg"crossorigin="anonymous"></a-assets><a-sky src = "# skyTexture" theta-length = "90" radio = "30"> </ a-cielo> <a la cámara > <a-entidad cursor = "downEvents: triggerdown; upEvents: triggerUp" geometría = "primitivo: anillo; radiusInner: 0,03; radiusOuter: 0,05" del material = "color: blue; shader: plana" posición = "0 0 - 1 "> </ a-entidad> </ a-cámara> <a-entidad id =" suelo "geometría =" primitivo: cilindro; radio: 30; altura: "posición =" 0.1 0 0 0 "del material =" shader: plana; color: # 424949" > </ a-entidad> </ a-escena> </ body> </p> <p> La sección de elementos pre-carga las imágenes y otros activos, como los modelos importados o archivos de audio, para mejorar el rendimiento de forma predeterminada. , a-Frame esperará hasta 3 segundos para los activos a la carga antes de iniciar la prestación. puede cambiar este valor mediante el establecimiento de un tiempo de espera en milisegundos como un atributo de <a-activos>. </ p> <P> Estamos cargando una textura de una de las aplicaciones de demostración de A-Frame. Dado que esta imagen no es nuestro propio dominio, tenemos que establecer el atributo crossorigin a “anónimo” para evitar que se genere una advertencia. </ P> <P> <a-cielo> es una primitiva que crea un fondo. En un nivel más bajo de abstracción, <a-cielo> es en realidad una esfera. Al establecer la fuente de #skyTexture, estamos utilizando la imagen cargada con ID skyTexture como imagen de fondo. El atributo “radio” establece el radio de la esfera. “Theta-longitud” es el ángulo de finalización del arco que incluimos en la escena. </ P> <P> <a la cámara> es un primitivo que representa la cámara. Normalmente, no es necesario especificar la cámara, pero queremos adjuntar una retícula a la cámara. Una retícula mirada controlado se crea al hacer una entidad con el componente de cursor. Los valores del parámetro de geometría hacen que el cursor un anillo azul. </ P> <P> La entidad creamos siguiente es un cilindro, que se especifica en el componente de geometría. Este cilindro sirve como el suelo. Dado que no se preocupan por el espesor del suelo, podemos hacer que sea muy delgada. El radio se establece en el mismo radio que <a-cielo>. Como resultado, el suelo se extiende hasta el horizonte. El componente de material establece el color y la iluminación del cilindro. </ P> <P> Para previsualizar la escena, ejecute NPM comenzar en su terminal. Un servidor web local empezará a ejecutarse en el puerto 3000, y una ventana de navegador puede abrir automáticamente que muestra la escena. Si no se abre automáticamente, vaya a la URL http: // localhost: 3000 en su navegador. Se puede mover el punto de mira y la vista arrastrando el ratón. Al hacer clic en el icono de las gafas cargas de la escena en una vista de pantalla completa. Si está viendo la página en un navegador en un dispositivo de realidad virtual, haciendo clic en el icono de gafas cambia al modo VR 360 grados. </ P> <P> Para ver la escena en la realidad virtual, cargar la escena en el navegador del teléfono móvil de los auriculares o, en sustitución del “localhost” con la dirección IP de la máquina de desarrollo. Si el equipo tiene un firewall que bloquea el acceso, y no quiere abrir un puerto, o si su dispositivo de realidad virtual no está en la misma LAN, se puede descargar e instalar ngrok para crear una URL temporal. </ P> <Img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x155.png" alt = "" /> </p> <h3> Creación de enemigos </ h3> <P> Para los enemigos en nuestro juego, vamos a utilizar un modelo 3D creado en Blender. El formato de archivo preferido para A-Frame es glTF, que se está convirtiendo en el estándar para los modelos 3D en la web. Blender no soporta de forma nativa glTF, pero el glTF-batidora-Exporteradd-on le permite exportar los modelos como glTF. Ver las instrucciones de este enlace para instalar el add-on. </ P> <Img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x274.png" alt = "" /> </p> <p> Exportar glTF de Blender crea a la vez un archivo .gltf y una .bin expediente. Dentro de su proyecto, crear la carpeta de activos / modelos y copiar ambos archivos a este directorio. El código fuente incluido para este tutorial incluye un modelo, Ghost.gltf y Ghost.bin, en los modelos activos / carpeta, que se puede utilizar. </ P> <P> Modelos están pre-cargados usando la etiqueta <a-activo-item>. Dentro de la sección-activos a, añadir: </ p> <A-activo-elemento id = "fantasma" src = "activos / Ghost.gltf"> </ a-activo-item> 1 <a-activo-elemento id = "fantasma" src = "activos / Ghost.gltf" > </ a-activo-item> </p> <p> Fuera de la sección de activos-a, crear entidades que carga el modelo fantasma: </ p> <A-entidad gltf-modelo = posición "# fantasma" = "0 1,6 -10"> </ a-entidad> <gltf-modelo = posición a-entidad "# fantasma" = "3 1,6 -10"> </ a-entidad> gltf-modelo = posición "# fantasma" a-entidad = "5 1,6 -10"> </ a-entidad> gltf-modelo = posición <123 <a-entidad "# fantasma" = "0 1,6 - 10 "</ a-entidad <a-entidad gltf-modelo =>>" "= posición" "</ a-entidad> <a-entidad gltf-modelo =>" posición # fantasma 3 1,6 -10 # fantasma "= "5 1,6 -10"> </ a-entidad> </p> <p> el-modelo gltf cesionarios de componentes del activo fantasma pre-cargado. El componente de posición fija el x, y, y las coordenadas z donde se encuentra la entidad. </ P> <P> Podemos hacer que responden a los clics fantasmas mediante la creación de un componente personalizado. Crear una carpeta, los activos / componentes, y un nuevo archivo, activos / componentes / cursor de listener.js, con el siguiente código: </ p> AFRAME.registerComponent ( 'cursor-oyente', {init: function () {var el = this.el; el.addEventListener ( 'clic', la función (evt) {el.parentNode.removeChild (el);});} }); 12345678AFRAME.registerComponent ( 'cursor-oyente', {init: function () {Varel = this.el; el.addEventListener ( 'clic', la función (evt) {el.parentNode.removeChild (el);}) ;}}); </p> <p> Cree otro archivo, activos / componentes / raycaster-autorefresh.js, con el siguiente código: </ p> AFRAME.registerComponent ( 'raycaster-autorefresh', {init: function () {var el = this.el; función this.el.addEventListener ( 'modelo cargado', () {var cursorEl = el.querySelector ( '[raycaster ] '); cursorEl.components.raycaster.refreshObjects ();});}}); 123456789AFRAME.registerComponent (' raycaster-autorefresh', {init: function () {Varel = this.el; this.el.addEventListener ( 'modelo cargado', function () {varcursorEl = el.querySelector ( '[raycaster]'); cursorEl.components.raycaster.refreshObjects ();});}}); </p> <p> Los componentes personalizados tienen que ser registrados por llamando AFRAME.registerComponent (). Esta función acepta el nombre del componente y la definición del componente como un objeto JavaScript. La definición contiene un esquema, la definición de los datos que se pueden transmitir al componente y manejadores del ciclo de vida, que son funciones pronunciado en varias pointsin ciclo de vida del componente. Los componentes de cursor-oyente y raycaster-AUTOREFRESH no contienen ningún dato. init es el controlador de llamada cuando el componente se añade primero al modelo de objeto de documento (DOM). </ p> <P> Nuestro primer componente, cursor de escucha, escucha por los clics del ratón sobre la entidad que ha añadido el componente. Cuando se detecta un clic, se elimina la entidad. this.el es la entidad en cuestión. Para mayor comodidad, la almacenamos en la variable y el llamado el.addEventListener () para adjuntar un oyente. Cuando se detecta el clic, la entidad se retira de su nodo padre, eliminando de forma eficaz desde el DOM. </ P> <P> El segundo componente, raycaster-autorefresh, es necesario refrescar la máquina de colada ray después de un modelo de cargas. Su uso está documentado en https://stackoverflow.com/questions/47032056/gltf-cursor-listener-click-event-in-a-frame. </ P> <P> Para poder utilizar los nuevos componentes, hay que incluirlos en index.html utilizando etiquetas script en la sección de cabecera: </ p> <Script src = "activos / componentes / cursor de listener.js"> </ script> <script src = "activos / componentes / raycaster-autorefresh.js"> </ script> 12 <script src = "activos / componentes / cursor-listener.js "> </ script> <script src =" activos / componentes / raycaster-autorefresh.js "> </ script> </p> <p> Añadir el componente raycaster-autorefresh a la escena cambiando el <a escena > etiqueta: </ p> <A-escena-raycaster autorefresh> 1 <a-escena-raycaster autorefresh> </p> <p> Añadir el componente cursor de oyente a cada fantasma: </ p> <A-entidad gltf-modelo = "# fantasma" posición del cursor-oyente = "0 1,6 -10"> </ a-entidad> <a-entidad gltf-modelo = posición del cursor-oyente "# fantasma" = "3 1,6 -10 "> </ a-entidad> <a-entidad gltf-modelo =" # fantasma "posición del cursor-oyente = "5 1,6 -10"> </ a-entidad> 123 <a-entidad gltf-modelo =" #ghost "posición del cursor-oyente =" 0 1,6 -10 "> </ a-entidad> <a-entidad gltf-modelo =" # fantasma "posición del cursor-oyente =" 3 1,6 -10" > </ a-entidad > <una entidad gltf-modelo = "# fantasma" posición del cursor-oyente = "5 1,6 -10"> </ a-entidad> </p> <p> Cuando se hace clic en un fantasma, ahora va a desaparecer. </ p> <Img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x184.png" alt = "" /> <img src = "http://fymm-rpg.net/wp- content / uploads / marcador de posición-300x154.png" alt = ""/> </p> <h3> automática Enemigo Creación </ h3> <P> En lugar de crear entidades enemigas a mano, podemos automatizar el proceso mediante la implementación de un nuevo componente para crear enemigos en el inicio del juego. Crear un nuevo archivo, activos / componentes / juego-manager.js, e incluirlo en index.html usando una etiqueta de script: </ p> <Script src = "activos / componentes / juego-manager.js"> </ script> 1 <script src = "activos / componentes / juego-manager.js"> </ script> </p> <p> <img src = "http : //fymm-rpg.net/wp-content/uploads/placeholder-200x300.png" alt = ""/> </ p> <P> En juego-manager.js, vamos a crear un nuevo componente, así como funciones de ayuda que va a generar entidades. Vamos a empezar con los ayudantes. Nos podría incrustar todas estas funciones en el propio componente, pero el código será más fácil de leer si mantenemos separados. </ P> GameManagerUtils var = {generateRandomNumber: function (min, max) {return Math.floor (Math.random () * max + min); }, ChooseRandomPosition: function () {xPos var = GameManagerUtils.generateRandomNumber (-10, 10); yPos var = 1,6; var ZPOS = GameManagerUtils.generateRandomNumber (-15, -30); retorno { 'x': xPos, 'y': yPos, 'z': ZPOS}; }, // Crear una nueva entidad enemiga. createEnemy: function () {console.log ( 'createEnemy'); var newEnemy = document.createElement ( 'a-entidad'); newEnemy.setAttribute ( 'gltf-modelo', '#ghost'); newEnemy.setAttribute ( 'cursor-oyente', ''); posición var = GameManagerUtils.chooseRandomPosition (); var positionStr = position.x.toString () + '' + position.y.toString () + '' + position.z.toString (); newEnemy.setAttribute ( 'posición', la posición); volver newEnemy; }}; 12345678910111213141516171819202122varGameManagerUtils = {generateRandomNumber: function (min, max) {returnMath.floor (Math.random () * max + min);}, chooseRandomPosition: function () {varxPos = GameManagerUtils.generateRandomNumber (-10,10); varyPos = 1,6; varzPos = GameManagerUtils.generateRandomNumber (-15, -30); retorno { 'x': xPos, 'y': yPos, 'z': ZPOS};}, // crear un nuevo enemigo entity.createEnemy: function () {console.log ( 'createEnemy'); varnewEnemy = document.createElement ( 'a-entidad'); newEnemy.setAttribute ( 'gltf-modelo', '# fantasma'); newEnemy.setAttribute ( 'cursor-oyente ' ''); varposition = GameManagerUtils.chooseRandomPosition (); varpositionStr = position.x.toString () +' '+ position.y.toString () +' '+ position.z.toString (); newEnemy.setAttribute ( 'posición', posición); returnnewEnemy;}}; </p> <p> Anteriormente, se había escrito elementos de una entidad con el atributo gltf-modelo. Ahora estamos utilizando la función GameManagerUtils.createEnemy () para generar nuevas entidades. createEnemy () llama a la función integrada de JavaScript document.createElement () para crear una nueva entidad con X generados al azar y coordenadas z. setAttribute () se llama para agregar los componentes gltf-modelo y cursor-oyente. </ p> <P> Ahora vamos a crear el componente de juego-manager. Recordemos que tenemos que llamar AFRAME.registerComponent () y definir manejadores de ciclo de vida, como init. Este es el código: </ p> AFRAME.registerComponent ( 'juego-manager', {esquema: {{numberEnemies: Tipo: int ''}}, init: function () {var = numEnemies this.data [ ''] numberEnemies; var = sceneEl document.querySelector ( 'a-escena'); var newEnemies = []; for (var i = 0; i <numEnemies; i ++) {newEnemies.push (GameManagerUtils.createEnemy ());} sceneEl.addEventListener ( 'cargado', function () {newEnemies.forEach (function (enemigo) {sceneEl.appendChild (enemigo);});});}}); 123456789101112131415161718AFRAME.registerComponent ( 'juego-manager', {esquema: {numberEnemies: {type: 'int'} }, init: function () {varnumEnemies = this.data [ 'numberEnemies']; varsceneEl = document.querySelector ( 'a-escena'); varnewEnemies = []; for (vari = 0; i <numEnemies; i ++) { newEnemies.push (GameManagerUtils.createEnemy ());} sceneEl.addEventListener ( 'cargado', function () {newEnemies.forEach (function (enemigo) {sceneEl.appendChild (enemigo);});});}}); <p> A diferencia del componente cursor-oyente, juego-manager acepta un parámetro entero, numberEnemies. El objeto de esquema define los parámetros y sus tipos de datos. Cuando se añade el componente de juego-gerente de una entidad, numberEnemies se pasa como un parámetro de estilo CSS en línea: </ p> <Una entidad juego-manager = “numberEnemies: 10”> </ a-entidad> 1 <una entidad juego-manager = “numberEnemies: 10”> </ a-entidad> </p> <p> Los datos del esquema se puede visitada en el objeto this.data. </ p> <P> El manejador init se llama cuando se inicie la componen. init llama GameManagerUtils.createEnemy () para generar numberEnemies entidades enemigas. También crea un detector de eventos que detecta cuando la escena se ha cargado. Una vez que se emite el evento ‘cargado’, todos los enemigos que se añaden a la escena. La escena se obtiene mediante la consulta para la etiqueta a-escena utilizando la función del modelo de objetos de documento querySelector (). Puede leer más sobre el DOM en https://developer.mozilla.org/en-US/docs/Web/API/Document. </ P> <P> Para utilizar este componente, incluyen juego-manager.js en index.html: </ p> <Script src = "activos / componentes / juego-manager.js"> </ script> 1 <script src = "activos / componentes / juego-manager.js"> </ script> </p> <p> Agregar el componente de juego-manager a la entidad una escena: </ p> <Una escena del juego-manager = "numberEnemies: 10" raycaster-autorefresh> 1 <a-escena del juego-manager = "numberEnemies: 10" raycaster-autorefresh> </p> <p> para generar enemigos diez, y comente el gltf-modelo entidades que crean manualmente en la última sección. </ p> <H3> Animaciones </ h3> <P> Por último, vamos a hacer que los enemigos se mueven. En A-Frame, animaciones se implementan mediante la a-animación primitiva o uniendo el componente de animación. De acuerdo con la documentación del componente de animación en https://github.com/ngokevin/kframe/tree/master/components/animation/, una animación con el tiempo se está desfasada y en el componente de animación. Por esta razón, vamos a utilizar el componente. </ P> <P> En index.html, incluye el componente de la animación en la sección de cabeza: </ p> <Script src = "https://unpkg.com/aframe-animation-component@4.0.0-beta8/dist/aframe-animation-component.min.js"> </ script> 1 <script src = "https: //unpkg.com/aframe-animation-component@4.0.0-beta8/dist/aframe-animation-component.min.js"></script></p> <p>Add las siguientes líneas a GameManagerUtils.createEnemy () en juego -manager.js antes se devuelve newEnemy: </ p><br /> var destinationStr = '0' + position.y.toString () + '0'; newEnemy.setAttribute ( 'animación', { 'propiedad': 'posición', 'a': destinationStr, 'autoplay': true, dur: 10000}); 12345vardestinationStr = '0 '+ position.y.toString () +' 0'; newEnemy.setAttribute ( 'animación', { 'propiedad': 'posición', 'a': destinationStr, 'autoplay': true , dur: 10000}); </p> <p> Esto anima la posición del enemigo, moviéndolo a las coordenadas representadas por destinationStr. Dado que la cámara está en (0, 0, 0), el enemigo se moverá hacia el origen, pero no cambiará su posición Y. La función de reproducción automática parámetro controla si la animación se inicia automáticamente. El dur, o duración, el parámetro, es la longitud de cada ciclo de animación en milisegundos. Ajustarlo con ensayo y error para obtener la velocidad deseada. </ P><br /> <P> <img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x182.png" alt = "" /> </ p><br /> <H3> Conclusión </ h3><br /> <P> Ahora que nos hemos familiarizado con los conceptos básicos de la A-Frame y ha creado un simple tirador WebVR, estamos listos para ver las funciones más avanzadas, como trabajar con los controladores de realidad virtual, que aparezcan los menús, y la adición de diferentes entornos. Vamos a explorar estos temas la próxima vez ya profundizar más en la A-Frame. </ P><br /> <H3> Mensajes relacionados </ h3><br /> <Img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-1232x533.png" alt = "" /> <img src = "http://fymm-rpg.net/wp- content / uploads / marcador de posición-1232x533.png" alt = "> <img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-1232x533.png" alt"/ = ""/></p> </div><!-- .entry-content --> </div><!-- .post-inner --> <div class="section-inner"> </div><!-- .section-inner --> <div class="comments-wrapper section-inner"> <div id="respond" class="comment-respond"> <h2 id="reply-title" class="comment-reply-title">Deja una respuesta <small><a rel="nofollow" id="cancel-comment-reply-link" href="/68-2/#respond" style="display:none;">Cancelar la respuesta</a></small></h2><form action="http://fymm-rpg.net/wp-comments-post.php" method="post" id="commentform" class="section-inner thin max-percentage" novalidate><p class="comment-notes"><span id="email-notes">Tu dirección de correo electrónico no será publicada.</span> Los campos obligatorios están marcados con <span class="required">*</span></p><p class="comment-form-comment"><label for="comment">Comentario</label> <textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required="required"></textarea></p><p class="comment-form-author"><label for="author">Nombre <span class="required">*</span></label> <input id="author" name="author" type="text" value="" size="30" maxlength="245" required='required' /></p> <p class="comment-form-email"><label for="email">Correo electrónico <span class="required">*</span></label> <input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" required='required' /></p> <p class="comment-form-url"><label for="url">Web</label> <input id="url" name="url" type="url" value="" size="30" maxlength="200" /></p> <p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" /> <label for="wp-comment-cookies-consent">Guardar mi nombre, correo electrónico y web en este navegador para la próxima vez que comente.</label></p> <p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="Publicar el comentario" /> <input type='hidden' name='comment_post_ID' value='68' id='comment_post_ID' /> <input type='hidden' name='comment_parent' id='comment_parent' value='0' /> </p></form> </div><!-- #respond --> </div><!-- .comments-wrapper --> </article><!-- .post --> </main><!-- #site-content --> <div class="footer-nav-widgets-wrapper header-footer-group"> <div class="footer-inner section-inner"> <aside class="footer-widgets-outer-wrapper" role="complementary"> <div class="footer-widgets-wrapper"> <div class="footer-widgets column-one grid-item"> <div class="widget widget_search"><div class="widget-content"><form role="search" method="get" class="search-form" action="http://fymm-rpg.net/"> <label for="search-form-2"> <span class="screen-reader-text">Buscar:</span> <input type="search" id="search-form-2" class="search-field" placeholder="Buscar …" value="" name="s" /> </label> <input type="submit" class="search-submit" value="Buscar" /> </form> </div></div> <div class="widget widget_recent_entries"><div class="widget-content"> <h2 class="widget-title subheading heading-size-3">Entradas recientes</h2> <ul> <li> <a href="http://fymm-rpg.net/2020/09/20/hola-mundo/">¡Hola, mundo!</a> </li> </ul> </div></div><div class="widget widget_recent_comments"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Comentarios recientes</h2><ul id="recentcomments"><li class="recentcomments"><span class="comment-author-link"><a href='https://wordpress.org/' rel='external nofollow ugc' class='url'>Un comentarista de WordPress</a></span> en <a href="http://fymm-rpg.net/2020/09/20/hola-mundo/#comment-1">¡Hola, mundo!</a></li></ul></div></div> </div> <div class="footer-widgets column-two grid-item"> <div class="widget widget_archive"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Archivos</h2> <ul> <li><a href='http://fymm-rpg.net/2020/09/'>septiembre 2020</a></li> </ul> </div></div><div class="widget widget_categories"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Categorías</h2> <ul> <li class="cat-item cat-item-1"><a href="http://fymm-rpg.net/category/sin-categoria/">Sin categoría</a> </li> </ul> </div></div><div class="widget widget_meta"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Meta</h2> <ul> <li><a href="http://fymm-rpg.net/wp-login.php">Acceder</a></li> <li><a href="http://fymm-rpg.net/feed/">Feed de entradas</a></li> <li><a href="http://fymm-rpg.net/comments/feed/">Feed de comentarios</a></li> <li><a href="https://es.wordpress.org/">WordPress.org</a></li> </ul> </div></div> </div> </div><!-- .footer-widgets-wrapper --> </aside><!-- .footer-widgets-outer-wrapper --> </div><!-- .footer-inner --> </div><!-- .footer-nav-widgets-wrapper --> <footer id="site-footer" role="contentinfo" class="header-footer-group"> <div class="section-inner"> <div class="footer-credits"> <p class="footer-copyright">© 2020 <a href="http://fymm-rpg.net/">Rpg Dev</a> </p><!-- .footer-copyright --> <p class="powered-by-wordpress"> <a href="https://es.wordpress.org/"> Funciona con WordPress </a> </p><!-- .powered-by-wordpress --> </div><!-- .footer-credits --> <a class="to-the-top" href="#site-header"> <span class="to-the-top-long"> Ir arriba <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-long --> <span class="to-the-top-short"> Subir <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-short --> </a><!-- .to-the-top --> </div><!-- .section-inner --> </footer><!-- #site-footer --> <script src='http://fymm-rpg.net/wp-includes/js/comment-reply.min.js?ver=5.4.3'></script> <script src='http://fymm-rpg.net/wp-includes/js/wp-embed.min.js?ver=5.4.3'></script> <script> /(trident|msie)/i.test(navigator.userAgent)&&document.getElementById&&window.addEventListener&&window.addEventListener("hashchange",function(){var t,e=location.hash.substring(1);/^[A-z0-9_-]+$/.test(e)&&(t=document.getElementById(e))&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())},!1); </script> </body> </html>