Creando bots para tus juegos en Pilas engine

 En este tutorial veremos como crear bots para nuestro juego, dichos bots pueden ser configurados para ,por ejemplo, que sean enemigos "inteligentes", o que jueguen contra nosotros al fútbol, o sean compañeros de batalla en una guerra de naves.

Primero lo primero ¿A qué le llamamos bot?

Se conoce como bot a programas que son capaces de jugar por sí mismos el juego en cuestión. La calidad del bot viene determinada por su capacidad de vencer en el videojuego (Bot. 2020, 2 de noviembre. Wikipedia, La enciclopedia libre.). Es decir, cuando creamos un bot para un juego en pilas, lo que hacemos es crear un actor capaz de jugar por si solo. 

Un Bot simple: Te persigue.

La idea es: mediante código haremos que un actor persiga a otro y que su rumbo se corrija cada segundo. ¿Cómo lo haremos? supongamos un conejito persigue a una zanahoria, en el código del conejito almacenamos en variables la posición de la zanahoria, luego hacemos que se dirija a esa posición.

Mas detalladamente: 

  1. Creamos un estado de autómata en el conejito llamado perseguir. 
  2. En el código del conejito, dentro de perseguir_cada_segundo() , obtenemos una referencia al actor zanahoria:
    let zanahoria = this.pilas.obtener_actor_por_nombre("zanahoria");
  3. En dos variables, xzanahoria yzanahoria, almacenamos la posición del actor zanahoria:
        let xzanahoria = zanahoria.x;
        let yzanahoria = zanahoria.y;
  4. hacemos que el conejo se dirija a  la posición (xzanahoria, yzanahoria):
        this.animar(Tipo.lineal, 1).mover_hasta(xz, yz, 2)
  5. Hacemos que el actor conejito entre en estado "perseguir" desde la función iniciar().
El código del conejito debería quedar así:
// @ts-ignore
class conejito extends Actor {

  iniciar() {
    this.estado = "perseguir"
  }

  actualizar() { }

  // Estado: perseguir

  perseguir_iniciar() {
 
  }

  perseguir_actualizar() {

  }

  perseguir_cuando_finaliza_animacion() {

  }

  perseguir_cada_segundo(segundos_transcurridos: number) {
    let zanahoria = this.pilas.obtener_actor_por_nombre("zanahoria");
    //estas variables(xzanahoria, yzanahoria)
    //guardan la posición del actor zanahoria
    let xzanahoria = zanahoria.x;
    let yzanahoria = zanahoria.y;
    this.animar(Tipo.lineal, 1).mover_hasta(xzanahoria, yzanahoria, 2);   
  }
}

Esto hará que el actor conejito persiga al actor zanahoria. Notar que yo puse de etiqueta y nombre conejito, si copian y pegan este código y el actor no se llama ni tiene por etiqueta a conejito sino conejo, les dará error.

Otra cosa importante es que para mover el conejo hacia la zanahoria, lo hicimos mediante la función this.animar, pero podría usarse otros métodos como por ejemplo this.avanzar(angulo_con_zanahoria, 10) y calculando el ángulo_con_zanahoria con this.pilas.obtener_angulo_entre_puntos(this.x, this.y, xzanahoria, yzanahoria).

Este bot puede mejorarse y hacerlo más rápido si hacemos todo directamente desde la función perseguir_actualizar().

 Para ello cortamos el código que pusimos en perseguir_cada_segundo() y lo pegamos en perseguir_actualizar()Esto hará que el rumbo se actualice 30 ó 60 veces por segundos, pero su velocidad puede volverse incontrolable y se vuelve muy difícil coordinar el cambio a otro estado.

Un paso más: patrulla, te persigue y dispara.

Llevemos el bot al siguiente nivel:  Crearemos un Guardia que vigila una zona, si nos ve, entones nos persigue y si se acerca mucho, entonces nos dispara. 

La idea es: Crearemos un actor llamado Guardia con un estados de autómata y una función, al comenzar estará quieto, pero si nos ve cambiará al estado perseguir que antes usamos para el conejito y si se nos acerca mucho, se ejecuta la función disparar la cual creará el actor bala que se va a dirigir hacia nosotros.

La idea es que el estado de autómata y la función sean estos:

  • Estado perseguir: Aquí pondremos el código que usamos antes para que el conejo persiga a la zanahoria. La diferencia está en que se activará si estamos a menos de 230 de distancia.
  • función disparar: Se invocará si la distancia al jugador es menor que 130, al activarse creará un actor bala.
Aquí les dejo el archivo para que vean como quedaría este bot (click sobre el texto en azul para descargar).

De manera general

A modo de cierre pensemos en cómo construir un bot. Lo primero sería identificar ¿qué debe hacer el bot? ¿cómo lo haría yo si fuera el bot? y ¿cómo programo esos comportamientos?. Para dejarlo más claro pensemos en cómo construir un actor que sea capaz de jugar al fútbol.

  • Al preguntarnos ¿qué debe hacer el bot? me refiero a cuáles son específicamente los comportamientos que debe hacer. En el caso de jugador de fútbol, ¿Qué debe hacer cuando se encuentra con la pelota? podríamos pensar en que al chocarla la patee, pero si al patearla se hace gol en contra, ¿la debe patear igual? está claro que no, entonces debe patearla siempre en dirección al arco o portería rival, y si el rival tiene la pelota, ¿qué debe hacer el bot?. Y así sucesivamente debemos desglosar todos los comportamientos para cada uno de los casos posibles tratando de imitar la manera en que nosotros lo haríamos.
  • Lo siguiente sería pensar en cómo lo programamos, para ello podemos usar una función creada por nosotros o un estado de autómata. Usaremos una función para realizar una acción en concreto una sola vez, como patear la pelota, y usaremos un estado de autómata cuando querramos que un comportamiento se mantenga en el tiempo, como el de buscar la pelota. 
En sí la idea es descomponer los comportamientos del bot en cadenas lógicas de SI...ENTONCES ya que estas cadenas se traducen fácilmente en if(condicion) {orden a ejecutar}.

Muchas gracias por leer.

Comentarios

Entradas populares de este blog

Comenzando en Pilas Engine 2

Movimientos en círculos

Cómo escribir código en pilas engine 2