Juego de Mago
En esta lección, combinaremos nuestro motor de VFX con muchas de las cosas que hemos aprendido durante este curso para crear un juego 3D simple: Un mago luchando contra viles orcos usando hechizos y magia. 🧙♂️
Una base sólida para tus propios proyectos de desarrollo de juegos web.
Proyecto Inicial
El proyecto inicial contiene:
- Una escena de práctica que preparé usando el modelo de Arcada encontrado en Poly Pizza por Poly by Google CC-BY
- Modelos de un Mago y un Orco de Quaternius. Ambos riggeados y animados.
- Un círculo animado que sigue el cursor del ratón
- Configuración básica de iluminación con sombras
- Un componente
<UI />
casi vacío, hecho con Tailwind CSS - Efectos de sonido para los hechizos encontrados en SoundEffectLab
Aquí tienes cómo se ve el proyecto inicial.
¿Listo para comenzar? 🪄
Bienvenido a Hogwarts 🏰
Antes de implementar cualquier tipo de lógica de juego, practiquemos nuestras habilidades mágicas en Hogwarts creando hechizos utilizando el motor de VFX que construimos en la lección dedicada.
Como hicimos en la lección de fuegos artificiales, podemos usar la versión publicada del motor de VFX. Vamos a añadirlo a nuestro proyecto:
yarn add wawa-vfx@^1.0.0
Al usar
@^1.0.0
, nos aseguramos de utilizar siempre la versión principal 1 del paquete pero incluyendo las versiones menores y de parches más recientes. De esta manera, podemos beneficiarnos de las últimas características y correcciones de errores sin cambios rompientes.
Ahora en el archivo Magic.jsx
, vamos a crear un componente <VFXS />
que contendrá todos nuestros componentes <VFXParticles />
para nuestro proyecto.
import { VFXParticles } from "wawa-vfx"; export const Magic = ({ ...props }) => { // ... return ( <group {...props}> <VFXS /> {/* ... */} </group> ); }; const VFXS = () => { return ( <> <VFXParticles name="sparks" settings={{ nbParticles: 100000, renderMode: "billboard", intensity: 3, fadeSize: [0.1, 0.1], }} /> ); };
Y junto a él, un componente Spells
que contendrá la parte de renderizado de nuestros hechizos.
// ... export const Magic = ({ ...props }) => { // ... return ( <group {...props}> <VFXS /> <Spells /> {/* ... */} </group> ); }; const Spells = () => { return <></>; };
Me gusta mezclar múltiples componentes en el mismo archivo cuando están estrechamente relacionados. Hace que sea más fácil entender la lógica del archivo. Si lo prefieres, siéntete libre de dividirlos en carpetas/archivos separados.
Vamos a preparar nuestro primer hechizo, el hechizo de Void.
Hechizo del Vacío
Vamos a crear un componente llamado Void
que se renderizará en el componente Spells
.
// ... import { VFXEmitter } from "wawa-vfx"; // ... const Spells = () => { return ( <> <Void /> </> ); }; const Void = ({ ...props }) => { return ( <group {...props}> <VFXEmitter debug emitter="sparks" /> </group> ); };
El componente VFXEmitter
emitirá partículas desde el emisor sparks
que creamos en el componente VFXS
.
Con debug
establecido en true
tendremos controles visuales para dar forma al efecto que queremos lograr.
Bien, ¡vamos a crear un hechizo que hará temblar a los orcos!
Un buen efecto VFX es una combinación de los ajustes correctos y el tiempo adecuado.
Descompongamos lo que queremos lograr con el hechizo Void.
Primero, queremos una fase de carga. Esto es cuando se reúne la energía antes de lanzar el hechizo. Cuanto mejor esté hecha, más anticipación sentirá el jugador y más poderoso se verá el hechizo.
Nuestra fase de carga estará compuesta por:
- Partículas emitidas lentamente hacia arriba
- Una esfera en crecimiento
- Runas escritas giratorias en el suelo como si se estuviera lanzando el hechizo
Luego, queremos la fase de explosión. Esto es cuando se lanza el hechizo y se libera la energía. Cuanto mejor esté hecha, más satisfactorio será para el jugador.
Nuestra explosión estará compuesta por:
- La esfera explotando (haciendo que desaparezca)
- Partículas yendo en todas las direcciones
Y para cada efecto visual, añadiremos un efecto de sonido para hacerlo más inmersivo.
Vamos a jugar con los ajustes del componente VFXEmitter
para lograr el efecto deseado para las partículas de carga.
Esto es lo que se me ocurrió:
<VFXEmitter emitter="sparks" settings={{ duration: 0.5, delay: 0, nbParticles: 20, spawnMode: "time", loop: false, startPositionMin: [-0.5, 0, -0.5], startPositionMax: [0.5, 1, 0.5], startRotationMin: [0, 0, 0], startRotationMax: [0, 0, 0], particlesLifetime: [0.5, 1], speed: [0, 1], directionMin: [0, 0, 0], directionMax: [0, 0.1, 0], rotationSpeedMin: [0, 0, 0], rotationSpeedMax: [0, 0, 0], colorStart: ["#4902ff"], colorEnd: ["#ffffff"], size: [0.1, 0.4], }} />
Podemos ver las partículas subiendo lentamente.
En lugar de partículas cuadradas, vamos a usar triángulos. Para hacerlo podemos usar una cone geometry con los ajustes apropiados.
// ... const VFXS = () => { return ( <> <VFXParticles name="sparks" geometry={<coneGeometry args={[0.5, 1, 8, 1]} />} settings={{ nbParticles: 100000, renderMode: "billboard", intensity: 3, fadeSize: [0.1, 0.1], }} /> </> ); }; // ...
Las partículas ahora tienen forma de triángulos.
Ahora añadamos la esfera en crecimiento. Para hacerlo necesitamos añadir un nuevo componente VFXParticles
al componente VFXS
:
const VFXS = () => { return ( <> {/* ... */} <VFXParticles name="spheres" geometry={<sphereGeometry args={[1, 32, 32]} />} settings={{ nbParticles: 1000, renderMode: "mesh", intensity: 5, fadeSize: [0.7, 0.9], fadeAlpha: [0, 1], }} /> </> ); };
Al establecer fadeSize
a [0.7, 0.9]
hacemos que la esfera crezca lentamente hasta el 70%
de su vida útil y luego desaparezca rápidamente durante el último 10%
.
React Three Fiber: The Ultimate Guide to 3D Web Development
✨ You have reached the end of the preview ✨
Go to the next level with Three.js and React Three Fiber!
Get full access to this lesson and the complete course when you enroll:
- 🔓 Full lesson videos with no limits
- 💻 Access to the final source code
- 🎓 Course progress tracking & completion
- 💬 Invite to our private Discord community
One-time payment. Lifetime updates included.