Encuentra el código fuente de este ejemplo aquí.

Phaser de fotones Storm es uno de los marcos más confiable para el desarrollo de juegos 2D de calidad profesional en JavaScript. Con Phaser, es factible hacer juegos performant que se ejecutan sin problemas en todos los principales navegadores, en todos los principales sistemas, mientras que sólo el tener que mantener una base de código. Y ahora, la última entrega de Phaser ha hecho su debut:. Phaser 3

Pero, ¿sabía que el mismo código que se ejecuta en el navegador pueden ser envueltos en una aplicación móvil “nativo”? Al combinar Phaser 3 con Apache Cordova, podemos producir juegos que no sólo se ejecutan en el navegador, pero también se pueden publicar en la App Store y Google Play Store.

En este artículo, vamos a utilizar Phaser para hacer un simple “juego” que se puede construir para iOS, Android y la Web. Aunque el resultado no será verdaderamente un “juego” en el sentido jugable, los conceptos serán referenciadas introduce de nuevo en futuros tutoriales donde, de hecho, crear juegos jugables.

Tabla de contenidos

Pre-requisitos (cosas para instalar!)

Vamos a estar tratando con puramente JavaScript (y poco de HTML) a través de este tutorial, por lo que todo lo que necesita para instalar manualmente es Node.js. Esto le dará los ejecutables de nodo y de la NGP en su sistema.

Una vez que se instala Node.js, descarga la línea de comandos de Apache Cordova ejecutando este comando en el comando / terminal de línea de comandos:
NPM i -g Cordova

Aprender Phaser 3 con nuestro nuevo mini-Grado

El desarrollo del juego HTML5 Mini-Grado ya está disponible para pre-pedido en Zenva Academia. Aprender a código y hacer que los juegos impresionantes con JavaScript y Phaser 3!

El acceso al instante temprano

Configuración del Proyecto

Cordova incluye proyectos repetitivo que hacen que sea mucho más fácil de empezar con un proyecto habilitada para móviles, así que vamos a tomar ventaja de que, mediante la ejecución de:
Córdova crear hola

Esto creará un directorio llamado hola, y copiar varios archivos en el proyecto.

A continuación, vamos a instalar Phaser en nuestro proyecto. En nuestro directorio del proyecto, ejecute lo siguiente:
cd wwwnpm initnpm i –save phaser123cdwwwnpm initnpmi – Guardar Phaser

Para aquellos no familiarizados con la NGP, las descargas de mando encima del código fuente del marco Phaser y guarda una copia local en la carpeta www / node_modules. De esta manera, tenemos una copia del código sin tener que descargarlo desde un CDN en cada carrera. La razón por la que tiene que tener un archivo package.json independiente en el directorio www es que los archivos estáticos se sirven desde el directorio www, y no de nuestra raíz del proyecto. Si Phaser se instala en la raíz del proyecto, que nunca sería capaz de acceder a él en el navegador.

A continuación, añadir el apoyo de let para el funcionamiento de nuestra aplicación en un navegador. Vamos a añadir soporte para ejecutar en iOS y Android más tarde. Ejecutar este:
Cordova plataforma complemento del navegador plataforma browser1cordova complemento

A continuación, vamos a querer añadir soporte para Live-recarga nuestros cambios cuando editamos nuestro archivo. De lo contrario, Córdoba referida solamente servir a una versión de nuestros archivos, lo que conducirá a una gran cantidad de rascarse la cabeza y preguntándose por qué errores aparentemente no desaparecen, incluso después de cambiar su código! Ejecutar este comando:
Cordova Cordova añadir plug-in-plugin-browsersync1cordova complemento complemento Cordova-plugin-browsersync

Ahora que hemos establecido nuestro proyecto para el desarrollo, vamos a ejecutar el servidor HTTP:
Cordova navegador de ejecución del navegador –live-reload1cordova run – vivo-recarga

Ahora, usted debe ser capaz de visitar http: // localhost: 8000 / index.html para ver su juego en acción .

Basic Código de Juego

En primer lugar, vamos a eliminar el código de arranque que nos da Córdova; que no va a necesitar más. Retire el

código en index.html, y añadir una referencia a nuestra fuente Phaser descargado, por lo que el archivo tiene el siguiente, haciendo caso omiso de los comentarios:
Hello World </ title> </ head> <body> <script type =" text / javascript "src =" cordova.js "> </ script> <script type =" text / javascript" src = "JS / index.js"> </ script> </ body> </ html> 1234567891011121314 <html> <head > <meta http-equiv = "Content-Seguridad-política" content = "default-src 'auto' de datos: distancia: https://ssl.gstatic.com 'inseguro-eval'; estilo-src 'auto' 'insegura -inline '; los medios de comunicación-src *; img src- 'datos auto': contenido:; "> <meta name =" formato de detección "content =" teléfono = no "> <meta name =" msapplication-tap-destacado "Content =" no "> <meta name =" viewport "content =" =-escalable usuario no, inicial escala = 1, de máxima escala = 1, mínimo escala = 1, width = dispositivo de anchura "> <link rel = "stylesheet" type = "text / css" href = "css / index.css"> <title> Hello World </ title> </ head> <body> <script type = "text / javascript" src =" cordova.js "> </ script> <script type =" text / javascript "src =" js / index.js "> </ script> </ body> </ html> </p> <p> No dude en eliminar el Content- la etiqueta de seguridad en políticas en la cabeza. Aunque es una opción inteligente para la seguridad, si no está familiarizado con el PSC, que puede ser un obstáculo en lugar confuso para un sencillo tutorial tales. </ P><br /> <P> A continuación, vamos a añadir algo de código en JS / index.js para iniciar una instancia de Phaser: </ p><br /> document.addEventListener ( 'deviceready', function () {var config = {type: Phaser.WEBGL, padre: 'juego', escena: {precarga: precarga, de creación: create}}; juego var = new Phaser.Game (config );) función de precarga ({} create () {}}); 123456789101112131415161718document.addEventListener ( 'deviceready', function () {varconfig = {type: Phaser.WEBGL, padre: 'juego', escena: {precarga: precarga , crear: crear}}; vargame = newPhaser.Game (config); functionpreload () {} functioncreate () {}}); </p> <p> Incluso en este relativamente pequeño fragmento de código, hay un poco pasando: </ p ><br /> <Ol><br /> <Li> crear un objeto de configuración, que se pasa al constructor Phaser.Game para especificar que el marco debe llamar a nuestro código. </ Li><br /> <Li> Indicamos a Phaser, a través de, escriba: Phaser.WEBGL, que queremos usar el procesador basado en WebGL, que es más rápido que la visualización basada en 2D lienzo liso </ li>.<br /> <Li> Le decimos Phaser para rendir en un lt existente y, lienzos & gt; donde id = "juego", o para crear tales a & lt; lona & gt; elemento si no existe uno. </ li><br /> <Li> incrustar un objeto de escena, lo que apunta a dos funciones Phaser llamará en diferentes puntos en el ciclo de vida del juego. </ Li><br /> </ Ol><br /> <P> Ahora, vamos a ejecutar nuestro juego! Escriba lo siguiente en el terminal: </ p><br /> Cordova navegador run - run navegador --livereload1cordova ---- LiveReload </p> <p> A continuación, para ver realmente el juego en su navegador, visite http: // localhost: 8000 en su navegador. Echa un vistazo a la salida! </ P><br /> <P> <img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x202.png" alt = "pantalla en negro vacío para el nuevo juego basado Phaser" /> </ p><br /> <P> Beautiful! Es una pantalla en negro vacío! </ P><br /> <H3> Adición juego de objetos </ h3><br /> <P> Como podrán imaginar, nadie quiere sentarse allí y mirar a una pantalla infinitamente-blanco. Así que vamos a darle sabor y añadir algo que se mueve! </ P><br /> <P> Phaser mucho tiempo se ha basado en la programación orientada a objetos, pero Phaser 3 introduce la categorización de ciertos objetos como <em> los objetos del juego </ em>, que comparten una funcionalidad común, mientras que el logro de objetivos diferentes. El tipo de juego de objetos se irán sumando ahora se denomina <em> sprites </ em>, que en la “imagen que representa un objeto.” 2D significa el mundo Los ejemplos más comunes de sprites animados incluyen sprites, que a menudo se utilizan para representar los caracteres en los juegos. </ p><br /> <P> A pesar de que un sprite por sí mismo es sólo una imagen, en el contexto de un motor de juego como Phaser, con frecuencia se asocia con cálculos de física, y proporciona una abstracción a través del cual un juego de programación puede cambiar lo que es visible en la pantalla de manera lógica camino. </ p><br /> <P> El uso de un activo de Kenney, vamos a cargar una imagen y dibujar a la pantalla. </ P><br /> <P> <img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x149.png" alt = "pantalla de archivo con sheet.png y sheet.xml seleccionado" /> </ p ><br /> <P> En primer lugar, descargar nos dejó el paquete de activos Tappy avión. Copia spritesheet / sheet.png y spritesheet / sheet.xml en el directorio www / img local. Vamos a cargar estos en nuestro juego modificando nuestra precarga y crear funciones de la siguiente manera: </ p><br /> función de precarga () {this.load.atlas ( 'hoja', '/ img sheet.png', '/ img sheet.json');} {this.add.sprite (400, 300, 'hoja función Crear () ', 'planeBlue1.png');} 1234567functionpreload () {this.load.atlas ( 'hoja', 'img / sheet.png', 'img / sheet.json');} functioncreate () {this.add. Sprite (400.300, 'hoja', 'planeBlue1.png.');} </p> <p> Tenga en cuenta que img / sheet.json está incluido en los activos del proyecto, y se basa en el contenido de img / sheet.xml </ p><br /> <P> Un poco ocurrió en las líneas anteriores. En primer lugar, hemos dicho Phaser que tenemos un archivo de textura, img / sheet.png, y que el marco debe utilizar el contenido de img / sheet.json para encontrar la localización de los marcos dentro de la imagen. img / sheet.json contiene un mapa de tramas que los nombres de mapa (es decir planeBlue1.png) a distintas localizaciones y tamaños dentro del archivo de textura, que contiene todo el paquete Tappy Plane comprimido en una sola imagen. </ p><br /> <P> A continuación, hemos creado un sprite que las referencias planeBlue1.png dentro de nuestro activo hoja. Como se mencionó anteriormente, aunque un Sprite es sólo una imagen, en la Phaser, podemos utilizarlo para realizar cálculos de física y otras transformaciones complejas. </ P><br /> <P> Actualiza la página para ver el juego actual: </ p><br /> <P> <img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x189.png" alt = "Phaser 3 juego con objeto avión" /> </ p><br /> <H3> Animación de la Sprite </ h3><br /> <P> El sprite plano azul incluido en el paquete Tappy Plano de Kenney incluye tres marcos, que se pueden combinar para crear una animación. Cambiar la función de crear la siguiente manera: </ p><br /> función Crear () {this.anims.create ({clave: 'plano', repetición: -1, frameRate: 10, marcos: this.anims.generateFrameNames ( 'hoja', {start: 1, final: 3, prefijo: 'planeBlue', el sufijo: '.png'})}); avión var = this.add.sprite (400, 300, 'hoja') juego ( 'plano');} 12345678910functioncreate () {this.anims.create ({clave:. 'plano', repetición: -1, frameRate: 10, marcos: this.anims.generateFrameNames ( 'hoja', {start: 1, final: 3, prefijo: 'planeBlue', sufijo: 'png'})}); varplane = this.add.sprite (400300, 'hoja') juego ( 'plano');.} </p> <p> en primer lugar, se registra una configuración de la animación en AnimationManager de Phaser. Usando el ayudante generateFrameNames, se especifica que la animación contenga los cuadros planeBlue1.png, planeBlue2.png y planeBlue3.png. La animación creamos, llamado avión, se puede aplicar a cualquier sprites; Sin embargo, para este ejemplo, sólo vamos a aplicarlo a nuestro sprite de avión. </ p><br /> <P> A continuación, añadir .play ( 'plano') en nuestro instanciación del sprite avión. Actualizar la página, y verá la turbina del avión girar infinitamente! </ P><br /> <P> Tenga en cuenta que las claves de avión corresponde a la clave del objeto de animación que hemos creado. </ P><br /> <H3> Adición de un fondo </ h3><br /> <P> Por supuesto, un juego con un aburrido, fondo vacío es (generalmente) un aburrido, juego vacío. Vamos a añadir un sprite de fondo, a la derecha <em> antes </ em> creación de nuestro avión. cree debería tener este aspecto: </ p><br /> función de crear () {this.anims.create ({...}); . This.add.image (0, 0, 'hoja', 'background.png') setOrigin (0); avión var = this.add.sprite (400, 300, 'hoja') juego ( 'plano');.} 12345functioncreate () {this.anims.create ({...}); this.add.image (0 ., 0, 'hoja', 'background.png') setOrigin (0); varplane = this.add.sprite (400300, 'hoja') juego ( 'plano');.} </p> <p> Tenga en cuenta la setOrigin (0 ), que cuenta la imagen a la posición en sí de acuerdo con su esquina superior izquierda, en lugar de la mitad (el origen predeterminado es 0,5). </ p><br /> <P> Vamos a echar un vistazo en el juego ahora: </ p><br /> <P> <img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-300x188.png" alt = "Phaser 3 juego con sprites avión y fondo de la montaña" /> </ p><br /> <H3> Escala del juego </ h3><br /> <P> Como usted probablemente ha notado, todavía hay una gran cantidad de espacio muerto. Podemos eliminar este dimensionando de forma explícita el lienzo juego al tamaño de nuestra imagen de fondo, 800x480 de. </ P><br /> <P> Modificar la configuración del juego de esta manera: </ p><br /> var config = {type: Phaser.WEBGL, padre: 'juego', anchura: 800, altura: 480, escena: {precarga: precarga, crear: crear}}; 12345678910varconfig = {type: Phaser.WEBGL, padre: 'juego , anchura: 800, altura: 480, escena: {precarga: precarga, crear: crear}}; </p> <p> Y voila, el espacio vacío ido </ p><br /> <P> Una advertencia para el desarrollo móvil es que no hay garantía del tamaño de una pantalla. Incluso en el contexto de un dispositivo, un cambio de tamaño del interruptor de la ventana o la orientación puede tirar la limpieza de su juego completamente fuera de balance. Sin embargo, con un poco de matemática simple, podemos cambiar el tamaño responsablemente nuestro juego. Cambiar su función de crear la siguiente manera (fuente): </ p><br /> función de crear () {window.addEventListener ( 'redimensionamiento', cambio de tamaño); cambiar el tamaño de (); // código explicados omitido} 123456functioncreate () {window.addEventListener ( 'redimensionamiento', cambio de tamaño); cambio de tamaño (); // código explicados omitido} </p> <p> A continuación, implementar la función de cambio de tamaño que el redimensionamiento automático nuestro lienzo juego: </ p><br /> función de cambio de tamaño () {var lienzo = game.canvas, width = window.innerWidth, altura = window.innerHeight; var wratio = anchura / altura, ratio = canvas.width / canvas.height; si (wratio <ratio) {canvas.style.width = ancho + "px"; canvas.style.height = (anchura / ratio) + "px"; } Else {canvas.style.width = (relación altura *) + "px"; canvas.style.height = altura + "px"; }} 123456789101112functionresize () {varcanvas = game.canvas, width = window.innerWidth, altura = window.innerHeight; varwratio = anchura / altura, ratio = canvas.width / canvas.height; si (wratio <ratio) {canvas.style .width = ancho + "px"; canvas.style.height = (anchura / ratio) + "px";} else {canvas.style.width = (altura * ratio) + "px"; canvas.style.height = altura + "px";!}} <p> Ahora, el juego va a cambiar automáticamente el tamaño de la ventana cuando hace </ p><br /> <H3> Desplazamiento infinito </ h3><br /> <P> Como es la naturaleza de Tappy Plano y Flappy Bird, nuestro fondo debe desplazarse hasta el infinito. Afortunadamente, es fácil de implementar esto en Phaser. En primer lugar, vamos a actualizar nuestra configuración del juego a punto de una función de actualización vamos a crear. Esta función será llamada una vez por cuadro. </ P><br /> var config = {type: Phaser.WEBGL, padre: 'juego', anchura: 800, altura: 480, escena: {precarga: precarga, crear: crear, actualizar: update}}; 1234567891011varconfig = {type: Phaser.WEBGL, los padres: 'juego', anchura: 800, altura: 480, escena: {precarga: precarga, crear: crear, actualizar: update}}; </p> <p> a continuación, vamos a cambiar nuestra creación de la función de declarar la imagen de fondo como un <em > baldosa de sprites </ em> en su lugar. Un sprite azulejo es un sprite especial que puede actualizar su posición con respecto a la cámara, para crear paralaje / infinita de desplazamiento fenómenos. </ P><br /> . This.bg = this.add.tileSprite (0, 0, 800, 480, 'hoja', 'background.png') setOrigin (0); hoja 1this.bg = this.add.tileSprite (0,0,800,480, ' .', 'background.png') setOrigin (0); </p> <p> Por último, vamos a poner en práctica que en realidad la función de actualización: </ p><br /> actualización de la función () {this.bg.tilePositionX + = 5;} 123functionupdate () {this.bg.tilePositionX + = 5;} </p> <p> Actualizar el juego, y verá el fondo de desplazamiento de forma continua, repitiéndose una vez que alcanza el final de la pantalla. </ p><br /> <P> Tenga en cuenta que aunque somos <em> añadir </ em> a tilePositionX, parece que el fondo se está moviendo hacia la izquierda. Ayuda a pensar en los sprites de tejas como un fondo de pantalla sin fin, que sólo estamos viendo una determinada pieza de a la vez. Cuando aumenta la tilePositionX, esto es análogo a los ojos del espectador en movimiento hacia la derecha, lo que crea un efecto de paralaje en movimiento hacia la izquierda. </ P><br /> <H3> Construyendo el juego para iOS y Android </ h3><br /> <P> Ahora viene la parte divertida: Ejecución de nuestro juego en el móvil! En primer lugar, añadir el IOS y las plataformas Android a la base de código: </ p><br /> Cordova plataforma complemento ios android1cordova complemento plataforma iOS Android </p> <p> Si este error, es posible que tenga que eliminar el paquete-lock.json. </ p><br /> <P> A continuación, se puede utilizar Cordova ejecutar nuestra aplicación en un emulador: </ p><br /> Cordova emular ios </p> <p> Esto hará que nuestra aplicación en el simulador de iOS (de acuerdo, tendrá que instalar ese, que se suministra con XCode, en primer lugar): </ p><br /> <P> <img src = "http://fymm-rpg.net/wp-content/uploads/placeholder-164x300.png" alt = "simulador de iOS avión se volar Phaser 3 juego" /> </ p><br /> <H3> Distribución del juego </ h3><br /> <P> Por último, al final va a querer publicar y distribuir nuestro juego. Ya sea a través de la App Store, la tienda de Google Play, u otra plataforma de distribución de aplicaciones, nuestras necesidades de juego para ser descargable y de fácil acceso para que nuestros usuarios a poner sus manos sobre él. </ P><br /> <P> En primer lugar, usted necesita para construir su aplicación en modo de lanzamiento. Intente lo siguiente para iOS: </ p><br /> Cordova acumulación --release ios1cordova acumulación - IOS </p> <p> Los pasos para construir una solicitud debidamente firmada para iOS son bastante intensiva, e incluyen los siguientes pasos: </ p><br /> <Ul><br /> <Li> Firmar la solicitud </ li><br /> <Li> Registrar un ID de aplicación </ li><br /> <Li> Crear un perfil de aprovisionamiento </ li><br /> <Li> Modificar aplicación de configuración </ li><br /> <Li> Presentar a la App Store </ li><br /> </ Ul><br /> <P> Este proceso se resume muy bien en este artículo; por el bien de no reinventar la rueda, me he vinculado a ella, en lugar de volver a escribir el contenido. </ p><br /> <P> Después de eso, ya está! Buen trabajo. </ P><br /> <H3> Conclusión </ h3><br /> <P> Apache Cordova es una gran solución para ejecutar aplicaciones destinadas originalmente a los navegadores web en dispositivos móviles. Envolviendo tales aplicaciones en envolturas WebView, Córdoba nos permite producir un “nativo” (nótese las comillas) experiencia en múltiples plataformas. Esto es muy bueno para escribir juegos, ya que elimina la necesidad de volver a escribir código para dirigirse a diferentes plataformas. </ P><br /> <P> Con Phaser, podemos crear juegos con Córdoba que se ejecutan en el navegador, iOS y Android. </ P><br /> <P> se quedan por el siguiente tutorial, donde continuamos con el paquete plano Tappy y convertir esto en un juego real! </ P><br /> <H3> Mensajes relacionados </ h3><br /> <Img src = "http://fymm-rpg.net/wp-content/uploads/phaser-3-tutorial-zenva-150x150.png" alt = "Phaser 3 dragón ejemplo juego cruce tutorial" /> <img src = "http://fymm-rpg.net/wp-content/uploads/screen-shot-2018-10-28-at-3-13-44-pm-150x150.png" alt = "" /> <img src = "http://fymm-rpg.net/wp-content/uploads/screen-shot-2018-10-28-at-3-13-44-pm-150x150.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="/123-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='123' 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.2'></script> <script src='http://fymm-rpg.net/wp-includes/js/wp-embed.min.js?ver=5.4.2'></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>