Crea un Space Shooter con PlayCanvas Parte 1

PlayCanvas hace que sea muy fácil crear contenido interactivo en 3D para la web con tecnología WebGL. Es todo JavaScript, por lo que se ejecuta de forma nativa en el navegador sin ningún complemento. Es un motor bastante joven que solo existe desde 2014, pero ha ido ganando terreno rápidamente con nombres como Disney, King y Miniclip, que lo utilizan para desarrollar juegos.. 

Es una gran herramienta por dos razones principales: primero, es un motor de juego con todas las funciones, por lo que maneja todo, desde gráficos y colisiones hasta audio e incluso integración con gamepads / VR. (Por lo tanto, no tendrá que buscar bibliotecas externas o preocuparse por los problemas de compatibilidad del navegador para la mayoría de las cosas). El segundo, y lo que realmente hace que se destaque, es su editor basado en navegador..

Así es como se ve un proyecto de muestra en el editor en el navegador de PlayCanvas. Es una forma realmente poderosa y conveniente de organizar su trabajo o incluso colaborar con otros en tiempo real..

Si estás acostumbrado a trabajar con el motor de Unity, el editor de PlayCanvas debería parecerte familiar (incluso utiliza un sistema similar basado en componentes para unir la funcionalidad). A diferencia de Unity, PlayCanvas no es multiplataforma y solo puede publicar para la web. Sin embargo, si lo único que te importa es la web, esto termina siendo una gran ventaja, ya que el enfoque del motor en la web lo hace realmente rápido y liviano en comparación con la competencia..

Una nota final: mientras que el motor en sí es gratuito y de código abierto., El editor en línea y las herramientas solo son gratis para proyectos públicos..Sin duda, vale la pena pagar si está desarrollando un trabajo comercial con él, pero siempre puede usarlo simplemente como un marco de código de forma gratuita.. 

El resultado final

Esto es lo que vamos a crear:

Puedes probar una demo en vivo.

El proyecto en sí es público, por lo que puede hurgarlo y / o incluirlo en su página de proyecto.

No es necesario tener ninguna experiencia con los juegos 3D para seguir, pero asumiré cierta familiaridad básica con JavaScript.

Creando nuestro propio proyecto desde cero

El resultado final es una demostración relativamente simple en la que simplemente vuelas y empujas asteroides, pero cubre suficiente funcionalidad básica que será útil para hacer cualquier tipo de juego 3D. La Parte 1 cubrirá la configuración básica, trabajando con modelos, el sistema de física y los controles de la cámara. La Parte 2 cubrirá el sistema de viñetas, generando asteroides y trabajando con texto.

1. Configuración del proyecto 

Dirígete a playcanvas.com y crea una cuenta.

Una vez que hayas iniciado sesión, haz clic en proyectos lengüeta En el salpicadero y presiona la gran naranja. nuevo botón para crear un nuevo proyecto. Esto debería mostrar el cuadro de "nuevo proyecto". Seleccione "proyecto en blanco" y asígnele un nombre:

Una vez que hayas terminado, pulsa el crear botón en la parte inferior derecha Esto te enviará a la página de resumen del proyecto. Aquí, puedes acceder a tu configuración y agregar colaboradores. Por ahora solo nos sumergiremos en el proyecto, así que haz clic en la gran naranja. botón editor.

Cuando ingreses a tu primer proyecto, PlayCanvas te mostrará muchos consejos sobre su editor. Puedes descartarlos por ahora. Las principales cosas a tener en cuenta son:

  • El panel izquierdo (jerarquía) es una lista de todos tus objetos del mundo. Aquí también es donde puede agregar, duplicar o eliminar entidades de su escena..
  • El panel derecho (inspector) es donde se editan las propiedades del objeto seleccionado. Después de seleccionar un objeto (haciendo clic en él), podrá establecer su posición y orientación o adjuntar scripts y componentes. 
  • El panel inferior (activos) contiene todos sus activos. Aquí es donde puede cargar texturas o modelos 3D, así como crear scripts..
  • La escena central es donde puedes editar y construir tu mundo de juego.. 

2. Creando un objeto

Para crear un nuevo objeto en su escena, haga clic en el pequeño botón más en la parte superior del panel de jerarquía:

Nota: Es posible que accidentalmente cree un nuevo objeto dentro de uno ya existente. Esto es útil para construir objetos compuestos de varias partes o que están unidos de alguna manera. Puede mover objetos alrededor del panel de jerarquía para controlar el anidamiento. Arrástrelo a la Raíz objeto para colocarlo de nuevo en la parte superior de la jerarquía. 

Como ejemplo, voy a crear una nueva caja y colorearla de rojo. Para darle un color personalizado, tenemos que crear un nuevo material. Puede hacer esto en el panel de activos, ya sea haciendo clic derecho en cualquier lugar dentro del panel, o haciendo clic en el pequeño ícono de más:

Una vez creado, seleccione su material y asígnele un nombre descriptivo como "RedMaterial" (puede ver el campo de nombre en el panel de inspección).

Ahora desplácese hacia abajo difuso Sección y cambiar el color:

Una vez hecho esto, regrese y seleccione el nuevo cuadro que creó (ya sea haciendo clic en él en la escena o en el panel de jerarquía). A continuación, establezca su material al material personalizado que acabamos de crear:

¡Y la caja ahora debería ser roja! Tenga en cuenta que el material que creó se puede adjuntar a tantos objetos como desee..

3. Añadiendo Física

Para habilitar la física en un objeto, tenemos que agregar dos componentes: Cuerpo rígido y Colisión.

Agregue el cuerpo rígido haciendo clic en "Agregar componente" en el panel del inspector en su objeto:

Asegúrese de que su tipo esté configurado en dinámica:

Y luego agrega un componente de colisión de la misma manera. 

Ahora inicie su juego haciendo clic en el pequeño botón de juego en la parte superior derecha de su escena. ¡Deberías ver tu caja cayendo por el suelo! Para solucionarlo, también deberá agregar un cuerpo rígido y una colisión al avión, asegurándose de que su tipo de cuerpo rígido sea estático (para que no se caiga también). 

Desafío: solo por diversión, intente agregar una esfera e incline el plano ligeramente (ya sea en el eje X o Z) para verlo rodar.

Una nota sobre el sistema de componentes

Vale la pena hablar brevemente sobre el sistema de componentes, ya que es una parte fundamental de la arquitectura de PlayCanvas. Conceptualmente, la idea es separar la funcionalidad de los objetos. La mayor ventaja de esto es la capacidad de componer un comportamiento complejo a partir de componentes modulares más pequeños.

Por ejemplo, si miras la cámara en tu escena, notarás que no es un objeto especial. Es solo una entidad genérica con un componente de cámara adjunto. Puede acoplar un componente de la cámara a cualquier cosa para convertirla en una cámara, o adjuntar un cuerpo rígido y colisión a la cámara para convertirla en un objeto sólido (¡inténtelo!). 

Si tiene curiosidad, puede leer más sobre las ventajas e inconvenientes de los sistemas de componentes en la página de Wikipedia.

4. Añadiendo un modelo

Ahora que está cómodo con lo básico, podemos comenzar a armar nuestro juego espacial. Necesitamos al menos un barco y un asteroide para trabajar. Hay dos formas de agregar modelos:

Toma un modelo de la biblioteca de PlayCanvas 

PlayCanvas tiene una tienda (similar a la Tienda de Activos de Unity) en la que puede encontrar y descargar activos directamente en su proyecto. Para acceder a él, simplemente haga clic en biblioteca en el panel de activos.

La tienda es muy nueva, por lo que es bastante escasa, pero es un buen lugar para encontrar marcadores de posición o activos para experimentar. 

Utilicé el activo hovership de la tienda como mi barco jugador.

Sube tu propio modelo

PlayCanvas admite la carga de archivos FBX, OBJ, 3DS y COLLADA (DAE), pero prefiere FBX. Puede convertir fácilmente cualquier modelo 3D en FBX abriéndolo con Blender y exportándolo en el formato deseado.

Puedes encontrar el modelo de asteroide que usé en Blendswap.com. Tenga en cuenta que es posible que desee optimizar sus modelos 3D antes de usarlos en el juego. Por ejemplo, ese modelo de asteroide contiene más de 200,000 triángulos! Eso podría estar bien para un objeto especial en el juego, pero una vez que agregué más de cien asteroides en la escena, las cosas realmente se hicieron más lentas. El modificador Decimate de Blender es una manera fácil de optimizar tus modelos. Lo utilicé para reducir el modelo de asteroides a unos 7.000 triángulos sin perder demasiados detalles. 

Una vez que los modelos estén en su proyecto (puede que necesite actualizarlos si no los ve de inmediato en el panel de activos), puede agregarlos a su escena. La forma más sencilla de hacerlo es arrastrar el modelo a la escena:

Este es el modelo real en sí mismo que puede agregar a la escena. Los otros activos que lo rodean son la textura / material, etc..

Al igual que antes, agregue un cuerpo rígido y un componente de colisión a la nave. Un truco que podría hacer con la colisión es agregar la malla del objeto real como su propia forma de colisión. Esto daría como resultado una malla de colisión de píxeles perfectos, pero no sería muy eficiente. Para esta demostración, opté por una caja simple como mi forma de colisión (y una esfera para los asteroides) y edité el media extensión para que coincida aproximadamente con la forma del modelo.

Cómo compensar la forma de colisión

Un problema que podría encontrar al ajustar las formas de colisión es la incapacidad de compensarlo desde el centro. Una forma fácil de evitar esto (además de tener que compensar el modelo en sí mismo en algo como Blender antes de exportarlo) es crear un objeto principal que tenga la colisión y un cuerpo rígido, y un objeto secundario que tenga el modelo en sí. Por lo tanto, podría compensar el modelo como un niño en relación con el padre que contiene la colisión.. 

Así es como lo tengo configurado para el proyecto de demostración, así que puedes echarle un vistazo para ver cómo se hace..

5. Cambiando los ajustes de gravedad y escena

Dado que nuestro juego está configurado en el espacio, debemos anular la gravedad predeterminada. Puedes hacer esto en la configuración de la escena. En la parte inferior izquierda de la pantalla, haga clic en icono de engranaje. Esto abrirá las configuraciones en el panel del inspector. Encuentra la sección de física y cambia el valor de la gravedad:

Para asegurarse de que funcionó, intente iniciar nuevamente y ver si el barco está flotando en el espacio.

No es bastante espacio sin un fondo estrellado, así que mientras estamos en la configuración de la escena, agreguemos un skybox. Puedes tomar uno de la tienda o simplemente encontrar uno en línea que te guste. Una vez que lo tengas, agrégalo a la sección de renderizado:

Eso debería darle al juego un poco más. nebuloso sensación. Este también sería un buen momento para limpiar su escena y eliminar cualquier objeto de prueba que hayamos creado antes..

6. Scripting la nave

Aquí es donde finalmente podemos escribir un código. El sistema de guiones de PlayCanvas es otra cosa que debería ser familiar si has usado Unity. Crea scripts que pueden adjuntarse a cualquier objeto, y estos scripts pueden tener atributos que se configuran sobre una base por objeto. Los atributos del script son muy útiles y logran dos cosas principales:

  1. Modularidad. Puedes crear un script que defina cómo se mueve un enemigo con un atributo de velocidad y reutilizarlo para diferentes tipos de enemigos con diferentes velocidades.. 
  2. Colaboración. Los atributos del script se pueden ajustar directamente en el editor sin tener que tocar ningún código. Esto permite a los diseñadores entrar y modificar los valores por sí mismos sin tener que molestar al programador o revisar el código. 

Crear un script

Vaya a la pestaña de activos y cree un nuevo activo de tipo Guión. Este será el código para el comportamiento del barco, así que llámalo como "Volar". Haga doble clic en él para abrir el editor de scripts..

El manual del usuario de PlayCanvas es una referencia muy útil al escribir scripts, como lo es la referencia de la API. La finalización automática también hace que sea muy fácil averiguar qué métodos están disponibles. Empezaremos haciendo girar nuestra nave. Escriba esto en el actualizar función:

this.entity.rigidbody.applyTorque (0,1,0);

Dentro de cualquier script, esta se refiere al componente de script en sí, mientras que esta.entidad se refiere al objeto al que se adjunta el script. Puede acceder a cualquiera de los componentes adjuntos a la entidad de esta manera. Aquí accedemos al cuerpo rígido y le aplicamos una fuerza angular.. 

Asegúrate de guardar tu script ahora.

Adjuntar un guión

Antes de que nuestro script se involucre demasiado, adjúntelo a nuestro barco para ver si funciona. Para hacer eso, solo agrega un componente de script a su nave, y luego agregue su script "volar" a eso. Tenga en cuenta que solo puede agregar un componente de secuencia de comandos por objeto, pero puede agregar varias secuencias de comandos dentro de ese componente.

Una vez que lances, deberías ver tu nave girando!

Añadir un atributo

Como se mencionó anteriormente, los atributos de script hacen que nuestro código sea mucho más flexible. Puede agregar uno escribiendo esto en la parte superior de su código, justo después de la primera línea donde se crea el script:

Fly.attributes.add ('speed', type: 'number', por defecto: 10, title: 'Ship Speed');

En este caso, el nombre de mi script es Volar. La única opción requerida es tipo.

Para ver el atributo en el editor, vuelva a su componente de secuencia de comandos y haga clic en el icono con dos flechas en la secuencia de comandos de mosca. Este es el botón de análisis que buscará cualquier atributo y actualizará el editor. Tu componente ahora debería verse así:

Finalmente, para usar el valor del atributo en su script, simplemente haga esto. [nombre_atributo]. Entonces, si quisiéramos que esta fuera la velocidad de rotación, podríamos cambiar nuestra línea de código a:

this.entity.rigidbody.applyTorque (0, this.speed, 0);

Nota: Como no hay amortiguación angular, la nave seguirá girando más rápido a medida que se aplique la fuerza. Si elimina la fuerza, mantendrá su inercia y seguirá girando a la misma velocidad. Para cambiar esto, establezca la amortiguación angular en el componente de cuerpo rígido a algo por encima de cero. 

Movimiento con las teclas de flecha

Ahora queremos escribirlo para que podamos orientar la nave con las teclas de flecha. Un enfoque ingenuo podría verse así:

Fly.prototype.update = function (dt) if (this.app.keyboard.isPressed (pc.KEY_RIGHT)) this.entity.rigidbody.applyTorque (0, this.speed, 0);  if (this.app.keyboard.isPressed (pc.KEY_LEFT)) this.entity.rigidbody.applyTorque (0, this.speed * -1,0);  if (this.app.keyboard.isPressed (pc.KEY_UP)) this.entity.rigidbody.applyTorque (this.speed * -1,0,0);  if (this.app.keyboard.isPressed (pc.KEY_DOWN)) this.entity.rigidbody.applyTorque (this.speed, 0,0); ;

¿Puedes decir cuál es el problema con este script? Pruébalo. ¿Puedes fácilmente apuntar el barco a donde quieras?? 

Piénsalo un poco antes de seguir leyendo. ¿Cómo arreglarías esto??

El problema es que estamos aplicando una fuerza en coordenadas globales sin tener en cuenta dónde se encuentra el barco. Si el barco es horizontal con respecto a la cámara, y lo giramos en el eje y cuando presionamos a la izquierda / derecha, entonces gira correctamente. Pero si el barco es vertical, una rotación en el eje y ahora es un barril.

El mismo problema pasaría si intentáramos avanzar también el barco. La dirección que es "hacia adelante" depende de dónde se enfrenta el barco y no puede ser absoluta. 

Ahora convenientemente, cada entidad tiene tres vectores de dirección que podemos usar: arriba, Correcto, y adelante. Para girar a la izquierda / derecha, giramos a lo largo de la arriba eje, y arriba y abajo giramos a lo largo del Correcto eje. Estos son arriba y Correcto en relación a la entidad. Una versión fija se vería así:

Fly.prototype.update = function (dt) var horizontalForce = this.entity.up.clone (); var verticalForce = this.entity.right.clone (); if (this.app.keyboard.isPressed (pc.KEY_RIGHT)) this.entity.rigidbody.applyTorque (horizontalForce.scale (this.speed * -1));  if (this.app.keyboard.isPressed (pc.KEY_LEFT)) this.entity.rigidbody.applyTorque (horizontalForce.scale (this.speed));  if (this.app.keyboard.isPressed (pc.KEY_UP)) this.entity.rigidbody.applyTorque (verticalForce.scale (this.speed * -1));  if (this.app.keyboard.isPressed (pc.KEY_DOWN)) this.entity.rigidbody.applyTorque (verticalForce.scale (this.speed)); ;

Agregar movimiento hacia adelante es la misma idea:

if (this.app.keyboard.isPressed (pc.KEY_Z)) this.entity.rigidbody.applyForce (this.entity.forward.clone (). scale (-1)); 

Si el movimiento se siente apagado o demasiado resbaladizo, dedique un poco de tiempo a ajustar las velocidades y los factores de amortiguación para llegar a donde se siente bien..

7. Controles de la cámara 

Es difícil hacer un seguimiento de un barco en movimiento con una cámara estática. La forma más fácil de hacer que la cámara siga un objeto es simplemente colocando la cámara como un elemento secundario de ese objeto..

Intenta arrastrar la cámara en el panel de jerarquía a tu nave. Una forma conveniente de ajustar la vista de la cámara es cambiando a la vista de la cámara en escena. Haga clic en el botón en la parte superior de la pantalla donde dice Perspectiva. Esto le dará un menú desplegable con todas las diferentes vistas de escena que puede seleccionar. Seleccionar Cámara, ¿Cuál debería ser el más alejado? Esta es una vista especial porque lo que vea en el editor es lo que verá la cámara en el juego. 

Una vez que haya ajustado la vista de la cámara, asegúrese de volver a la perspectiva o cualquier otra vista para evitar estropear accidentalmente los ángulos de la cámara..

Propina: Si tiene un objeto seleccionado en la jerarquía, pero no puede encontrarlo en su escena, presione F. Esto enfocará la vista en ese objeto y lo ampliará. Puede ver más atajos de teclado haciendo clic en el botón del teclado en el extremo izquierdo de su pantalla.

En este punto, debes tener una cámara siguiendo tu nave (por muy rígida que sea). (No podrá saber si se está moviendo si la cámara se está moviendo y no hay otros objetos en el mundo, así que intente agregar algunos).

Guiones de cámara

Una cámara que se haya quedado atascada en el reproductor no es muy interesante. Esta publicación en el blog PlayCanvas explora varios tipos diferentes de movimiento de cámara. El más sencillo que podemos implementar es el mira la camara.

Para hacerlo, primero mueva la cámara hacia el objeto raíz.. 

A continuación, crea un nuevo script llamado mirar

La función de actualización de ese script debe verse como:

LookAt.prototype.update = function (dt) this.entity.lookAt (this.target.getPosition ()); ;

Y debería tener un atributo:

LookAt.attributes.add ('target', type: 'entity');

Ahora adjunte ese script al objeto de la cámara. Presiona el botón Parse y establece el objetivo para que sea la entidad del barco..

Intenta lanzar! Si todo salió bien, su cámara permanecerá en su lugar, pero solo se orientará hacia el barco..

Puedes implementar los otros tipos de cámaras de la misma manera. los al final de la cámara de seguimiento mencionado en la publicación del blog lo ideal es que se vea mejor, pero me parece que está demasiado nervioso cuando la velocidad de cuadros cae un poco, así que para la demostración final, terminé yendo con una cámara que estaba unida a la nave cuando era niño. con guión para mover y rotar como lo hizo la nave.

Conclusión

No se preocupe si algo de esto se siente un poco abrumador. PlayCanvas es un motor complejo con muchas campanas y silbidos. Hay mucho que explorar, y mantener el manual cerca es una buena manera de orientarse. Otra buena manera de aprender es simplemente encontrando proyectos públicos y observando cómo se hacen las cosas..

La Parte 2 comenzará con la creación de un sistema de viñetas, y luego agregará algunos asteroides para disparar, y lo completaremos agregando un contador de FPS y un texto dentro del juego. Si tiene alguna solicitud o sugerencia, o si algo no está claro, hágamelo saber en los comentarios!