pilas-engine

¿como hacer un actor que vuele y persiga a otro?

Quiero crear una especie de murciélago, que este pegado al techo y, cuando se acerca otro actor, se baje, y que se mueva más o menos de forma aleatoria (a veces siga al protagonista, pero no siempre). También quiero poder hacer que cambie entre dinámico y no dinámico desde el código, para que no le afecte la gravedad hasta que quiera

Novedad, mientras programaba mi actor, me sale un error, la idea es que si pasas por abajo, hace una animación y todo eso, pero cuando termina la animación, me sale un error, adjunto el proyecto.
Abrir este proyecto en el editor de pilas

Te mueves con W, A, S, D (hay mas cosas, pero para probar esto en concreto, es lo necesario)

Hola @Varalan !!!

Te comento cómo hacer que un actor siga a otro, primero tienes que
crear el actor murciélago y hacerle 3 estados:

  • reposando
  • avanzando
  • regresando

Podrías hacer más estados como “golpeando” o “muriendo”, pero yo
solo hice esos 3 para simplificar las cosas.

Este es un diagrama de estados que suelo armar cuando se presenta un personaje
como este, dibujar el diagrama me ayuda a diseñar el comportamiento del actor
antes de llevarlo al código:

Esta idea de “estados” es muy útil, es lo que te permite hacer que un actor
pueda hacer distintas cosas y comportarse como un autómata. Creo que ya viste
este concepto antes, pero por las dudas te recomiendo ver este video en youtube sobre autómatas en pilas y revisar esta parte del manual donde
se explica como usarlos.

Te paso un ejemplo donde implementé estos estados, vas a notar que el murciélago
se despierta cuando está muy cerca del protagonista (el conejo) y luego regresa
a su posición cuando el protagonista se aleja muy rápido:

Abrir este proyecto en el editor de pilas

Oh, por cierto, los gráficos de murciélagos los tomé de este
pack de imágenes gratuitas:

Ah, y sobre tu consulta del error: no llegué a encontrar el error, a simple vista no me
pude dar cuenta dónde estaba. Pero más tarde voy a intentar revisarlo
en detalle a ver si puedo encontrar dónde está el problema.

Te escribo en cuanto llegue a verlo, ¡Abrazo!

1 Like

Muchas gracias, si bien los estados autómata ya los estaba usando, tu método es mucho mas practico. Sin embargo, ahora en mi proyecto me sale un error, cuando el protagonista muere sale un error, “se intentó acceder a un actor eliminado”, creo que es porque el murciélago está constantemente verificando la ubicación del protagonista, pero cuando muere, el protagonista se elimina para dar un efecto de muerte, ¿Hay alguna forma de que solo verifique su ubicación mientras el actor exista y sí se elimina, deje de verificarlo?

Ahhh, es cierto, ahí me di cuenta que mi código tenía un error: resulta que si el actor se puede eliminar en algún momento, tenemos que tener cuidado de llamar a la función para obtener la distancia al protagonista.

Lo correcto sería consultar si el actor existe antes de consultar la distancia a él:

if (!this.protagonista.esta_vivo()) {
    return false;
}

let distancia = this.obtener_distancia_al_actor(this.protagonista);

y lo mismo sucedería con otras consultas al actor, por ejemplo si quieres
poner un observador en pantalla, que accede al protagonista, tendrías que
asegurarte que el actor esté vivo:

if (this.protagonista.esta_vivo()) {
  let distancia = this.obtener_distancia_al_actor(this.protagonista);
  this.pilas.observar("distancia", distancia);
} else {
  this.pilas.observar("distancia", "?? el actor se eliminó");
}

Aquí te paso la versión modificada con algunos cambios:

Abrir este proyecto en el editor de pilas

Cambié los métodos actualizar, esta_cerca, esta_lejos y avanzando_actualizar.

¡Avisame cualquier cosa!

2 Likes

Gracias, me sirvió mucho, cualquier cosa te aviso si me sale un error.

Hola @Varalan, sobre el error de la animación que dices. Si no lo resolvieron aún, es por que

wake_actualizar() {
    this.y -= 1;

    if (this.pies.cantidad_de_colisiones_con_la_etiqueta("plataforma") >= 1) {
      this.espejado_vertical = false;
    }
  }

El condicional if compara la cantidad de colisiones del sensor pies con un número, pero si el sensor ya no colisiona, entonces el método cantidad_de_colisiones_con_la_etiqueta devuelve undefined (no recuerdo como se escribe xd) y como no es un número, devuelve error ya que el sígno >= busca comparar números con el 1.
La solución es decir que si no hay colisiones, entonces ese if no se ejecute.
A mi se me ocurre preguntar si colisiona:

if (this.pies.colisiona_con_etiqueta("plataforma")) {
      this.espejado_vertical = false;
    }

Debería ser lo mismo, ya que relamente no te importan cuántas veces colisione, no importa, según tú código, si coliona 1 ó 2 ó mil veces, importa que no sean 0 veces.

1 Like

Gracias, aunque ya solucioné el error, esto me ayudará más adelante