NOTA:. Este tutorial no se actualiza a la versión más reciente Quinto y no correr con ella strong> p> HTML5 Mario-estilo de plataformas Series con Quinto: p> ¿Es un hablante de francés? Si es así, gracias a Alejandro Bianchi se puede disfrutar de una adaptada versión francesa de este tutorial. P> Este tutorial es la segunda parte de la serie de plataformas Quinto. En el primer tutorial que hemos aprendido algunos conceptos básicos del marco, construyen un nivel básico usando el editor de mapas de baldosa, cargamos el nivel en nuestro juego e implementado una clase de Jugador que podemos controlar mediante el teclado y moverse alrededor del nivel. P> En este segundo tutorial vamos a añadir enemigos al nivel. Vamos a implementar dos tipos de enemigos: “los enemigos de tierra” y “enemigos verticales”. También vamos a cubrir cómo podemos tener nuestros enemigos escanear el entorno que les rodea y actuar en consecuencia. p> Tabla de contenidos p> Si usted está disfrutando de este tutorial y quiere mucho más de estas cosas no dude en visitar nuestra desarrollo de juegos HTML5 cursos en línea que cubren todos los aspectos básicos para empezar: p> p> Como ya se mencionó en la introducción, debe haber completado el tutorial anterior Quinto. Los requisitos para estos serie de tutoriales son: p> Obtener el código fuente completo tutorial y las imágenes aquí. Todas las imágenes utilizadas en este tutorial tienen una licencia de dominio público. P> Comenzaremos creando una nueva clase que hereda de Q.Sprite. VerticalEnemies como yo los he llamado será moscas exóticas que sólo se mueven arriba y abajo. Usted puede caminar sobre ellos para matarlos y si las toca en cualquier otra forma que podrás matar. P> El movimiento vertical estará dentro de un rango. Vamos a llamar a la distancia se moverán de su ubicación inicial “rangey”. Así que si defino rangey = 100 significa que se moverán 100 píxeles hacia arriba desde el principio, luego hacia abajo hasta que van de 100 píxeles de la ubicación inicial. P> analise Vamos paso a paso. Definimos nuestra clase y le dan un valor predeterminado rangey de 200 píxeles. También hemos establecido la gravedad a 0, lo que significa que no se caigan al suelo, pero flotarán en su lugar (la gravedad viene dada por el componente 2d, que todavía necesitamos para la detección de colisiones más fácil). El parámetro initialy almacenará la ubicación inicial en el eje Y, lo que vamos a utilizar en nuestros cálculos. P> El paso () será ejecutado varias veces por segundo y será utilizado para comprobar las cosas que “deben ser controladas todo el tiempo”. Esto es lo que llamamos el juego Loop, un concepto importante en el desarrollo del juego. El dt parámetro representa la cantidad de tiempo en segundos que ha pasado desde el método de la etapa () se llama pasado. P> Vamos a añadir el código dentro de la etapa () para comprobar que nos estamos moviendo dentro de nuestra gama, y con las instrucciones del interruptor una vez se llega a las fronteras de este rango: p> en Quinto y cuando se utiliza la etiqueta canvas (y en todos los demás marcos de juego que estoy familiarizado con la materia) el eje comienza en cero en la parte superior y es positivo cuando va hacia abajo. El eje X es igual a cero a la izquierda como de costumbre. P> Si llegamos a la parte inferior de la gama mientras se mueve arriba (vy es nuestra velocidad en Y, lo que es positivo cuando va hacia abajo) entonces debemos cambiar de dirección (ajuste vy a -vy). Lo mismo se aplica para cuando se va para arriba. P> Así que esa es la forma en que podemos utilizar el paso () para comprobar si hay cosas en cada iteración del juego. Empezar a pensar en todas las posibilidades que esto abre y lo poderoso que es. En el bucle del juego se puede comprobar y actualizar casi todo. En realidad, así es como funciona el marco detrás de las escenas! si se abre quintus_2d.js encontrará el paso () que se utiliza para la detección de colisiones, movimiento, etc. p> Entonces, ¿qué si toca las moscas? vamos, que depende de donde se tocan (y sí, todavía estamos hablando de desarrollo del juego aquí). Si pisas, los matas (puro estilo Mario). Si usted los golpea a ambos lados o en la parte inferior luego de su muerte. Vamos a añadir el código restante: p> Con this.on estamos escuchando para eventos. Los eventos son unos elementos centrales en el marco Quinto y es así como se puede escuchar por ellos. Encontrará la definición de la protuberancia. * Eventos dentro quintus_2d.js. P> Cuando se activa la colisión, se puede comprobar la clase de elemento que hemos chocado con el uso de collision.obj.isA (…). P> Si el jugador golpea al enemigo en todos los lados, excepto la parte superior un “game over” escena tendrá lugar (todavía tenemos que crearla) y el jugador objeto destruido. P> Si pisamos los enemigos, el jugador recibe un poco hacia atrás de rebote y el enemigo es destruido. P> En el siguiente tutorial vamos a implementar vidas jugador. Por ahora el juego va a ser duro, si se muere una vez que el juego ha terminado. Y por simplicidad estamos sólo va a volver a cargar la página en el juego. Agregue el siguiente código escena puesta en escena: p> Dentro de la level1 inicialización puede crear enemigos de la misma manera que hemos creado el jugador: p> Usted debe ser capaz de crear, matar y morir por las moscas ahora p> p> El segundo tipo de enemigo se irán sumando aquí son criaturas que se mueven en el nivel del suelo (I GroundEnemies los llamó). Si llegan a un pasillo o el borde de un acantilado que se conviertan en su espalda y se mueven en la dirección opuesta (volteando el sprite así a la cara lo mismo). P> lo que hemos añadido anteriormente es más o menos la misma que añadido para el VerticalEnemy, con la única diferencia de que incluimos el componente “aiBounce”, que da a los enemigos un comportamiento básico: caminar y dar la vuelta al chocar con las paredes. Os recomiendo echar un vistazo a este componente en quintus_2d.js, ya que le dará más consejos sobre cómo crear su propia cuenta. P> Ya que estamos duplicando el código que lo mejor es crear un componente reutilizable llamado “commonEnemy” y actualizar el código un poco: p> se ejecuta la “) añadido (” método dentro de la creación de componentes una vez que el componente se carga al objeto. Vemos cómo el interior de este método se obtiene el enemigo por conseguir this.entity, después de lo cual se puede casi se refieren al enemigo como si estuviera en su propio método init (). P> Si se han fijado en el código anterior que he dejado el método el paso () de la GroundEnemy. Vamos a utilizar el bucle del juego para comprobar si hay cantos, si nuestros enemigos caerán por el acantilado. P> Antes de abandonar el código quiero explicar lo que estamos tratando de hacer:. P> La escalabilidad (la capacidad de crecer sin volverse loco) es un aspecto a tener en cuenta. Queremos ser capaces de crear rápidamente múltiples enemigos y no tener que crear las instancias individuales, uno por uno. P> Además, existe la posibilidad de que podemos desear para cargar los parámetros de nivel de Internet, en cuyo caso tenemos que ser capaces de material de carga de un objeto JSON. P> Sólo voy a mostrar una forma rápida para cargar los enemigos de nivel utilizando JSON. Se podría cargar una gran cantidad de otros parámetros de esta manera, y este objeto JSON podría provenir de Internet, el almacenamiento local, etc. El siguiente código de inicialización va dentro de nuestra level1, y utiliza un método Quinto etapas que han llamado “loadAssets”: p> Hemos llegado al final de este tutorial y antes de cerrar esto me gustaría sugerir algunas actividades que puede intentar por su cuenta: p> Si te gusta mi estilo de enseñanza, en Zenva strong> tenemos dos cursos de vídeo de alta calidad en el desarrollo de juegos HTML5 donde construimos varios ejemplos de diferentes tipos de juegos, como una vista superior disparar chicos malos juego al estilo Zelda, juegos de naves espaciales, la agricultura juegos, juegos de mascotas virtuales y muchos otros ejemplos! p> p>
Tutorial objetivos h2>
Ol>
HTML5 dev juego, así! H3>
Requisitos h2>
Ul>
Tutorial Activos h2>
El cara a cara! strong>
He proporcionado los archivos Quintus entre el código fuente tutorial, pero ten en cuenta que el marco es en fuerte desarrollo. Es mejor si usted acaba de agarrar ellos directamente desde la página de Github. Además, mantener un ojo en el repositorio como usted trabaja en sus partidos desde que se añaden nuevas características. Killer Moscas h2>
// enemigo que sube y downQ.Sprite.extend ( «VerticalEnemy», {init: function (p) {this._super (p, {vy: -100, rangey: 200, gravedad: 0}); this.add ( «2D»); this.p.initialY = this.py; // TODO: cheque por colisiones jugador, troquel o matar consecuencia}, paso: function (dt) {// TODO: movimiento gama actualización dentro del bucle de juego} }); 1234567891011121314 // enemigo que sube y downQ.Sprite.extend ( «VerticalEnemy», {init: function (p) {this._super (p, {vy: -100, rangey: 200, gravedad: 0}) ; this.add ( «2D»); this.p.initialY = this.py; // TODO: cheque por colisiones jugador, die o matar consecuencia}, paso: function (dt) {// TODO: movimiento gama actualización dentro de el bucle de juego}});
paso: function (dt) {if (this.py – this.p.initialY & gt; = this.p.rangeY & amp; & amp; this.p.vy & gt; 0) {this.p.vy = -this.p .vy; } Else if (-this.p.y + this.p.initialY & gt; = this.p.rangeY & amp; & amp; this.p.vy & lt; 0) {this.p.vy = -this.p.vy; }} 12345678step: function (dt) {if (this.py-this.p.initialY & gt; = this.p.rangeY & amp; & amp; this.p.vy & gt; 0) {this.p.vy = -this.p. vy;} elseif (-this.p.y + this.p.initialY & gt; = this.p.rangeY & amp; & amp; this.p.vy & lt; 0) {this.p.vy = -this.p.vy;} }
El cara a cara! strong>
Pase por lo menos media hora mirando el código de la biblioteca Quinto. No se limite a apoderarse de las cosas a partir de los ejemplos que encuentras en la web. Lo necesario para pasar el tiempo mirando cómo las ampollas de la obra marco. Usted se sorprenderá de lo intuitivo y sencillo que es.
init: function (p) {this._super (p, {vy: -100, rangey: 200, gravedad: 0}); this.add ( «2D»); this.p.initialY = this.p.y; this.on ( «bump.left, bump.right, bump.bottom», la función (colisión) {if (collision.obj.isA ( «Player»)) {Q.stageScene ( «Final de partida», 1, {label: «Juego sobre»}); collision.obj.destroy ();}}); this.on ( «bump.top», la función (colisión) {if (collision.obj.isA ( «Jugador»)) {collision.obj.p.vy = -100; this.destroy ();}}); }, 12345678910111213141516171819init: function (p) {this._super (p, {vy: -100, rangey: 200, gravedad: 0}); this.add ( «2D»); this.p.initialY = this.py; this.on ( «bump.left, bump.right, bump.bottom», la función (colisión) {if (collision.obj.isA ( «Player»)) {Q.stageScene ( «Final de partida», 1, {label: «Juego sobre»}); collision.obj.destroy ();}}); this.on ( «bump.top», la función (colisión) {if (collision.obj.isA ( «jugador»)) {colisión. obj.p.vy = -100; this.destroy ();}});},
Juego Escena Durante h2>
Q.scene ( «Final de partida», la función (etapa) {alert ( «game over»); window.location = «»;}); 1234Q.scene ( «Final de partida», la función (etapa) {alert ( «game over» ); window.location = «»;}); Mostrando los enemigos h2>
stage.insert (nuevo Q.VerticalEnemy ({x: 800, y: 120, rangey: 70, activo: «fly.png»})); 1stage.insert (newQ.VerticalEnemy ({x: 800, y: 120, rangey: 70, activo:. «fly.png»}));
Juicy limos h2>
// enemigo que camina alrededor Q.Sprite.extend ( «GroundEnemy», {init: function (p) {this._super (p, {VX: -100, defaultDirection: «izquierda»}); this.add ( «2d , aiBounce «); this.on (» bump.left, bump.right, bump.bottom», la función (colisión) {if (collision.obj.isA ( «jugador»)) {Q.stageScene ( «Final de partida», 1, {label: «Juego sobre»}); collision.obj.destroy ();}}); this.on ( «bump.top», la función (colisión) {if (collision.obj.isA ( «jugador» )) {// hacer que el jugador salto collision.obj.p.vy = -300; // matanza this.destroy enemigo ();}});}, paso: la función (dt) {// TODO para bordes y vuelta atrás cuando la búsqueda de ellos}}); // 1234567891011121314151617181920212223242526 enemigo que camina alrededor Q.Sprite.extend ( «GroundEnemy», {init: function (p) {this._super (p, {VX: -100, defaultDirection: «izquierda» }); this.add ( «2d, aiBounce»); this.on ( «bump.left, bump.right, bump.bottom», la función (colisión) {if (collision.obj.isA ( «jugador»)) {Q.stageScene ( «Final de partida», 1, {label: «Juego sobre»}); collision.obj.destroy ();}}); this.on ( «bump.top», la función (colisión) {if ( collision.obj.isA ( «Pl ayer «)) {// hacer que el jugador jumpcollision.obj.p.vy = -300; // enemythis.destroy kill ();}});}, paso: function (dt) {// TODO para bordes y a su vez atrás cuando la búsqueda de ellos}});
// componente para enemigo común behaviorsQ.component ( «commonEnemy», {añadido: function () {entidad var = this.entity; entity.on ( «bump.left, bump.right, bump.bottom», la función (colisión) {if (collision.obj.isA ( «jugador»)) {Q.stageScene ( «Final de partida», 1, {label: «Juego sobre»}); collision.obj.destroy ();}}); entity.on ( «bump.top», la función (colisión) {if (collision.obj.isA ( «jugador»)) {// hacer que el jugador salto collision.obj.p.vy = -100; // matanza enemigo this.destroy ();}});},}); // enemigo que camina alrededor Q.Sprite.extend ( «GroundEnemy», {init: function (p) {this._super (p, {VX: -100, defaultDirection: «izquierda»}); this.add ( «2d, aiBounce, commonEnemy»);}, paso: function (dt) {// TODO}}); // enemigo que sube y downQ.Sprite.extend ( «VerticalEnemy «, {init: function (p) {this._super (p, {vy: -100, rangey: 200, gravedad: 0}); this.add ( «2d, commonEnemy»); this.p.initialY = esta .py;}, paso: function (dt) {if (this.py – this.p.initialY & gt; = this.p.rangeY & amp; & amp; this.p.vy & gt; 0) {this.p.vy = -this.p.vy;} els E Si (-this.p.y + this.p.initialY & gt; = this.p.rangeY & amp; & amp; this.p.vy & lt; 0) {this.p.vy = -this.p.vy; }}}); 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 // componente para enemigo común behaviorsQ.component ( «commonEnemy», {añadido: function () {varentity = this.entity; entity.on ( «bump.left, bump.right, bump.bottom» , la función (colisión) {if (collision.obj.isA ( «jugador»)) {Q.stageScene ( «Final de partida», 1, {label: «Juego sobre»}); collision.obj.destroy ();}} ); entity.on ( «bump.top», la función (colisión) {if (collision.obj.isA ( «jugador»)) {// hacer que el jugador jumpcollision.obj.p.vy = -100; // matanza enemythis.destroy ();}});},}); // enemigo que camina alrededor Q.Sprite.extend ( «GroundEnemy», {init: function (p) {this._super (p, {VX: -100 , defaultDirection: «izquierda»}); this.add ( «2d, aiBounce, commonEnemy»);}, paso: function (dt) {// TODO}}); // enemigo que sube y downQ.Sprite.extend ( «VerticalEnemy», {init: function (p) {this._super (p, {vy: -100, rangey: 200, gravedad: 0}); this.add ( «2d, commonEnemy»); this.p. initialy = this.py;}, paso: function (dt) {if (this.py-this.p.initialY & gt; = this.p.rangeY & amp; & amp; this.p.vy & gt; 0) {this.p.vy = -ésimo is.p.vy;} elseif (-this.p.y + this.p.initialY & gt; = this.p.rangeY & amp; & amp; this.p.vy & lt; 0) {this.p.vy = -this.p .vy;}}});
Escaneado de Medio Ambiente h2>
Esta característica podría convertirse pronto en una parte del componente aiBounce
Ul>
paso: function (dt) {var DirX = this.p.vx / Math.abs (this.p.vx); suelo var = Q.stage () localizar (this.p.x, this.p.y + this.p.h / 2 + 1, Q.SPRITE_DEFAULT).; var nextTile = Q.stage () localizar (this.p.x + DirX * this.p.w / 2 + DirX, this.p.y + this.p.h / 2 + 1, Q.SPRITE_DEFAULT).; // si estamos en terreno y hay un acantilado si (nextTile & amp;! & Amp; tierra) {if (this.p.vx & gt; 0) {if (this.p.defaultDirection == «derecho») {este .p.flip = «x»; } Else {this.p.flip = false; }} Else {if (this.p.defaultDirection == «izquierda») {this.p.flip = «x»; } Else {this.p.flip = false; }} This.p.vx = -this.p.vx; }} 1234567891011121314151617181920212223242526step:. Función (dt) {vardirX = this.p.vx / Math.abs (this.p.vx); varground = Q.stage () localizar (this.px, this.p.y + esto. ph / 2 + 1, Q.SPRITE_DEFAULT); varnextTile = Q.stage () localizar (this.p.x + DirX * this.pw / 2 + DirX, this.p.y + this.ph / 2 + 1. , Q.SPRITE_DEFAULT); // si estamos en terreno y hay una cliffif (nextTile & amp;! & amp; tierra) {if (this.p.vx & gt; 0) {if (this.p.defaultDirection == «derecho» ) {this.p.flip = «x»;} else {this.p.flip = false;}} else {if (this.p.defaultDirection == «izquierda») {this.p.flip = «x» ;} else {this.p.flip = false;}} this.p.vx = -this.p.vx;}} Enemies en JSON h2>
// activos de nivel. formato debe ser como se muestra: [[NombredeClase, params], ..] levelAssets var = [[ «GroundEnemy», {x: 18 * 70, y: 6 * 70, activo: «slime.png»}], [» VerticalEnemy «{x: 800, y: 120, rangey: 70, activo: «fly.png»}], [ «VerticalEnemy», {x: 1.080, Y: 120, rangey: 80, de activos:» fly.png «}], [» GroundEnemy», {x: 6 * 70, y: 3 * 70, activo: «slime.png»}], [ «GroundEnemy», {x: 8 * 70, y: 70, de activos: «slime.png»}], [ «GroundEnemy», {x: 18 * 70, y: 120, activo: «slime.png»}], [ «GroundEnemy», {x: 12 * 70, y: 120, activo: «slime.png»}]]; // activos de nivel de carga stage.loadAssets (levelAssets); 12345678910111213 activos // nivel. formato debe ser como se muestra: [[NombredeClase, params], ..] varlevelAssets = [[ «GroundEnemy», {x: 18 * 70, y: 6 * 70, activo: «slime.png»}], [ «VerticalEnemy «, {x: 800, y: 120, rangey: 70, activo: «fly.png»}], [ «VerticalEnemy», {x: 1.080, Y: 120, rangey: 80, de activos: «fly.png» }], [ «GroundEnemy», {x: 6 * 70, y: 3 * 70, activo: «slime.png»}], [ «GroundEnemy», {x: 8 * 70, y: 70, activo:» slime.png «}], [» GroundEnemy», {x: 18 * 70, y: 120, activo: «slime.png»}], [ «GroundEnemy», {x: 12 * 70, y: 120, de activos : «slime.png»}]]; // nivel de carga assetsstage.loadAssets (levelAssets); sugerido Actividades h2>
Ul>
¿Qué más Material para verificar h2>
Mensajes relacionados h3>