Continuamos con la serie “Proyecto de recreación de juego clásico de los 80”, en este cuarto video/artículo abordamos la implementación de las mecánicas de disparo de los enemigos y sus proyectiles.
Si no has visto el episodio 3 de la serie, visítalo en este enlace: Disparos del jugador
En esta cuarta entrega del proyecto de remasterización vamos a implementar las mecánicas de juego relacionadas con el comportamiento de los enemigos. Dentro del escenario del primer nivel se encuentran dispersas unas “cabezas de dragón” que lanzan dos tipos de proyectiles:
- Burbujas Ácidas
- Salpicaduras
Ambos elementos surgen de la boca de las cabezas de dragón, tienen un tiempo de duración y restan un punto del escudo de la nave del jugador si impactan contra ella. Sin embargo, mientras que las burbujas pueden ser destruidas por los disparos del jugador, las salpicaduras sólo pueden ser evitadas.
Implementación de las burbujas
La implementación de las burbujas emplea un spritesheet de 4 imágenes de la misma burbuja con una ligera variación para que parezca vibrar en ver de resultar sólida.
Creamos entonces el prefab “burbuja”. Este permitirá crear múltiples burbujas al mismo tiempo cuando las cabezas de dragón las disparen:
Imagen del prefab de la burbuja de ácido
El prefab consta de un colisionador circular (CircleCollider2D) configurado como disparador (isTrigger) para detectar el solapamiento con los disparos del jugador. Igualmente incluye un componente de cuerpo rígido (RigidBody2D) de tipo cinemático para controlar directamente el movimiento sin implementar fuerzas.
En el juego original, las burbujas son proyectadas en abanico desde las bocas de los dragones, moviéndose a diferentes velocidades y desaparecen al de unos instantes.
Trayectoria de las burbujas de ácido lanzadas por los enemigos.
Esto lo implementamos en el script de control de las burbujas (AcidoControl):
using System.Collections;
using System.Collections.Generic; using UnityEngine; public class AcidoControl : MonoBehaviour { public float VelocidadMax; public float VelocidadMin; public float Angulo; public float Tiempo; private float velocidad; private Vector3 direccion; // Start is called before the first frame update void Start() { float rot = Random.Range(-Angulo, +Angulo); direccion = Quaternion.Euler(0.0f, 0.0f, rot) * Vector3.left; velocidad = Random.Range(VelocidadMin, VelocidadMax); Invoke(“Fin“, Tiempo); } void Fin() { Destroy(gameObject); } // Update is called once per frame void Update() { transform.Translate(direccion * velocidad * Time.deltaTime); } } |
Si estás interesado en ampliar tus conocimientos en el área creación, desarrollo y diseño de videojuegos, visita nuestros cursos de videojuegos
Los parámetros de ajuste del script que declaramos públicos para poder ajustarlos desde el editor de Unity son los siguientes:
- VelocidadMax y VelocidadMin à Determinan la velocidad lineal máxima y mínima entre las que se calcula aleatoriamente la velocidad de cada burbuja.
- Angulo à Determina la anchura del abanico con el que se desplazan las burbujas de modo que saldrán disparadas en un ángulo aleatorio en el rango (+Angulo/-Angulo) en relación a la dirección izquierda.
- Tiempo à Determina el tiempo en segundos de duración de las burbujas
El método Start() calcula aleatoriamente el vector de dirección a partir de un ángulo obtenido aleatoriamente entre los valores positivos y negativos del parámetro Angulo, y su velocidad aleatoria comprendida entre VelocidadMax y velocidadMin.
Ambos parámetros se aplican para desplazar el gameobject en el método Update().
Las burbujas sólo pueden solaparse contra la nave del jugador y sus disparos atravesando todos los demás elementos del escenario incluidos bloques y nubes:
Esquema de interacción entre elementos del escenario, disparos, jugador y las burbujas de ácido
Para esto creamos una capa “Ácido” y agregamos el prefab:
En la configuración de física del proyecto marcamos la intersección entre la capa “Acido” con las capas “Jugador” y “Laser”. De igual modo desmarcamos la intersección de la capa “Acido” consigo misma y la capa “Default”. Esto evita que las burbujas impacten entre ellas y con el resto de elementos del escenario:
Cuando una burbuja se solapa tanto con la nave del jugador como con un disparo resulta igualmente destruida. No obstante, en el caso del disparo puede aparecer un premio para el jugador. Por ello de momento implementamos únicamente la destrucción de la burbuja, pero diferenciando ambos casos. Para ello debe comprobarse el “tag” del gameobject contrario:
Los prefabs de los disparos llevan asociado un “tag” que permite identificarlos. Las instancias del prefab “Laser” llevan el tag “Laser”:
Por su lado, las instancias del prefab “nave” llevan el tag “Nave”:
De este modo el script (AcidControl) puede detectar si la burbuja se solapa contra la nave del jugador o uno de sus disparos. Para ello implementamos el método OnTriggerEnter2D() comprobando el valor de la propiedad tag del objeto collision recibido como parámetro:
void ImpactoJugador()
{ Debug.Log(“IMPACTO JUGADOR“); Destroy(gameObject); } void ImpactoLaser() { Debug.Log(“IMPACTO LASER“); Destroy(gameObject); } private void OnTriggerEnter2D(Collider2D collision) { switch( collision.tag) { case “Nave“: // El otro gameobject es el jugador. ImpactoJugador();break; case “Laser“: // El otro gameobject es un disparo del jugador ImpactoLaser(); break; } } |
Si estás interesado en ampliar tus conocimientos en el área creación, desarrollo y diseño de videojuegos, visita nuestros cursos de videojuegos
Implementación de las salpicaduras
Las salpicaduras son semejantes a las burbujas en su forma de moverse, pero a diferencia de éstas son invulnerables a los disparos del jugador.
Imagen del Prefab de la salpicadura
El prefab de la salpicadura posee un colisionador circular (CircleCollider2D) de tipo disparador (IsTrigger) y un cuerpo rígido (RigidBody2D) de tipo cinemático. Su movimiento es como al de las burbujas exceptuando por la velocidad que es siempre la misma.
El script de control (SalpicaduraControl) sería el siguiente:
public class SaplicaduraControl : MonoBehaviour
{ public float Velocidad; public float Angulo; public float Tiempo; private Vector3 direccion;
// Start is called before the first frame update void Start() { float rot = Random.Range(-Angulo, +Angulo); direccion = Quaternion.Euler(0.0f, 0.0f, rot) * Vector3.left; Invoke(“Fin“, Tiempo); } void Fin() { Destroy(gameObject); } // Update is called once per frame void Update() { transform.Translate(direccion * Velocidad * Time.deltaTime); } } |
Los parámetros públicos de este script son análogos a los de la burbuja (AcidControl). Sus valores de ajuste en la ventana de inspección son los siguientes:
Parámetros del script de control de las burbujas
Parámetros del script de control
En cuanto a los solapamientos, los prefab salpicadura definen su propia capa “Salpicadura”.
Esta sólo capa sólo interactúa con el jugador, de modo que las salpicaduras no interactúan ni entre ellas, ni con los disparos del jugador, ni con el resto de elementos del escenario. De igual modo, burbujas y salpicaduras no interactúan entre ellas:
Esquema de interacción entre elementos del escenario, disparos, jugador, burbujas y salpicaduras
Para ello configuramos la física de modo que la capa “Salpicadura” solo tiene activa la intersección con la capa “Jugador”:
Disparo de burbujas y salpicaduras por parte de los enemigos.
Las cabezas de dragón lanzan tanto burbujas como salpicaduras desde su boca con frecuencia variable. Para fijar la posición de ésta empleamos un gameobject “boca” vacío anidado situado justo donde el sprite del dragón tiene la boca:
Situación del gameobject anidado “Boca” determinando posición de generación de burbujas y salpicaduras.
Para controlar el lanzamiento de burbujas y salpicaduras añadimos al prefab de las cabezas de dragón el script de control “DragonControl”:
Este script consta con tres parámetros públicos:
- Acido -> Hace referencia al prefab “burbuja” para instanciar burbujas
- Salpicadura -> Referencia el prefab “salpicadura” para instanciar salpicaduras.
- Boca -> Referencia al componente de transformación del gameobject anidado “boca” que determina el punto de generación de burbujas y espumarajos.
public class DragonControl : MonoBehaviour
{ private bool vivo = true; private SpriteRenderer render; public GameObject Acido; public GameObject Saplicadura; public Transform boca; // Start is called before the first frame update void Start() { render = GetComponent<SpriteRenderer>(); StartCoroutine(AcidoCorutina()); } IEnumerator AcidoCorutina() { while( vivo ) { yield return new WaitForSeconds(0.25f); if (render.isVisible) { Instantiate(Acido, boca.position, Quaternion.identity); Instantiate(Saplicadura, boca.position, Quaternion.identity); } } } } |
Una corutina instancia de manera continua a intervalos de 0.25 segundos (4/segundo) una burbuja y una salpicadura desde la posición del gameobject “boca” mientras el dragón es visible. Para ello se comprueba el valor de la propiedad isVisible del componente SpriteRenderer. Esto ahorra tiempo de ejecución evitando que los enemigos generen burbujas y salpicaduras cuando no son visibles.
Si estás interesado en aprender a programar videojuegos, visita nuestro Curso de Unity 3D
Impactos contra el escudo del jugador.
Cuando una burbuja o una salpicadura impactan contra la nave del jugador debe reducirse un punto el escudo de la nave, que resultará destruida si llega a 0. Para controlarlo incluimos un segundo script (NaveColisionador) al prefab de la nave del jugador.
Este se encarga de detectar las colisiones contra otros gameobjects mediante el método OnTriggerEnter2D:
public class NaveColisionador : MonoBehaviour
{ public int Escudo; private void Daño() { Escudo–; // Reduce el nivel de escudo 1 punto. Debug.Log(“IMPACTO NAVE: “ + Escudo); } private void OnTriggerEnter2D(Collider2D collision) { switch( collision.tag ) { case “Salpicadura”: case “Acido”: Daño(); break; } } } |
Tanto si se trata de una salpicadura como si es una burbuja de ácido, se ejecuta el método Daño() que resta 1 al valor del atributo Escudo que representa el nº de impactos que es capaz de soportar la nave antes de resultar destruida.
Otros videos de la serie:
- Video 1. Análisis de juego y creación de proyecto
- Video 2. Creación de escenarios
- Video 3. Disparos del jugador