Comunidad de diseño web y desarrollo en internet online

Inteligencia Artificial parte 1

Citar            
MensajeEscrito el 19 Nov 2006 03:05 pm
La idea de este mini tutorial es explicar los conceptos básicos necesarios para generar inteligencia artificial en los videojuegos.

ADVERTENCIA: Este tutorial, de todos modos, está orintado a aquellos con conocimientos intermedios o avanzados de AS. Por lo que recomiendo que antes de leer lo que sigue, aquellos que recién empiezan con Flash, se den una vuelta por la sección de tutoriales de esta página y revisen los conceptos básicos de programación en AS.

Ahora, para empezar con el tema, hay que definir qué entendemos por inteligencia. La definición que me viene a la mente es la capacidad de aprender de nuestros errores y modificar nuestro comportamiento en base a ellos (aplicado a la programación, sería modificar el código ya escrito). Claro que esto es demasiado complicado, lo que nosotros buscamos es el tipo de inteligencia artificial (en adelante IA) encontrada en los videojuegos.

Entonces, la IA en los videojuegos se define como la imitación del comportamiento de jugadores de "carne y hueso" y es en eso en lo que nos vamos a basar. Claro que para hacer una IA de calidad es necesario emplear inteligencia real, para crear un código lo más simple posible que sea capaz de complicarle la vida a los videojugadores y, además, que el usuario no descubra brechas por las que puede confundir a nuestros autómatas (brechas que no deberían existir).

En este tutorial, vamos a armar un ejemplo en el que habrá unos cuantos clips de película, 1 que actuará de oveja y el resto, que actuarán de lobos. La idea va a ser que la oveja intentará escapar de los lobos que intentarán cazarla.

Para los lobos, podría hacerse un código simple que haga que se muevan en la dirección de la oveja. Pero el problema radica en que la oveja se mueve un 50% más rápido que ellos, lo que hace que este sistema se muestre inútil.

Pero entonces, uno podría pensar que es imposible. Pues no lo es, simplemente, hay que usar más de un lobo (es decir, una jauría). Entonces, del mismo modo en que ocurre en la naturaleza, los lobos deberían comportarse inteligentemente y organizarse para cazarla, rodeándola y evitando que se escape.


Ahora, las reglas. La oveja tendrá 2 estados, tranquila y asustada. Mientras esté tranquila se moverá un 20% más lento que los lobos, cuando se asuste, correrá a más no poder y esa velociadad será un 50% mayor que la velocidad de los lobos. Además, cambiará la forma en la que escapa de estos feroces carnívoros (en esta entrega, veremos solo el código que empleará para cuando está tranquila).

Otra regla, sería que los lobos, no pueden depender de variables externas (excepto la que determina su velocidad) ni acceder de ninguna manera a las variables de los otros lobos y la oveja (excepto las de posición, claro). Entonces, los prototipos de los lobos, podrían tener (eso va a depender de cada programador) más de un estado, como acechando y cazando, por ejemplo. El problema es que ningún lobo podrá acceder al estado de otro lobo o al estado de la oveja (eso es porque, aún, no han evolucionado los lobos telépatas).



Bien, ahora, luego de la teoría, un poco de código.

Este se va a ser escrito 100% en el único fotograma de la película (aunque habrá más de una capa), reemplazando el código en los MCs por prototipos (los prototipos son funciones que emulan código escrito en los símbolos). Además, por comodidad, vamos a trabajar con 4 capas, una en la que declararemos las variables, una donde ubicaremos los prototipos, una en la que irán las funciones y, finalmente, las acciones principales.



Vamos a comenzar por algunas funciones.

Lo primero, es una función que calcule la distancia entre 2 clips. Nada raro, un par de cuentas y un return.

Código :

calcularDistancia = function (objeto1:String, objeto2:String) {
   //
   // Calculamos la distancia en X y en Y
   var distX = _root[objeto1]._x - _root[objeto2]._x;
   var distY = _root[objeto1]._y - _root[objeto2]._y;
   //
   // Calculamos la distancia
   var distancia = Math.sqrt ((distX * distX) + (distY * distY));
   //
   return distancia;
};


Luego, una función que usará la oveja para detectar cúal es el lobo que se halla más cerca usando la función [i]calcularDistancia[\i].


Código :

buscarLobos = function (oveja:String, numeroLobos:Number) {
   //
   var distMin = 1000;
   var lobo;
   //
   for (i = 1; i <= (numeroLobos + 7); i++) {
      //
      // Calcular la distancia para cada uno de los lobos
      var distancia = calcularDistancia (oveja, "lobo" + i);
      //
      // Si la distancia es la distancia más pequeña encontrada, la variable lobo nos devuelve el lobo más cercano       a la oveja
      if (distancia < distMin) {
         lobo = "lobo" + i;
         distMin = distancia;
      }
   }
   return lobo;
};


Bien, ahora, la función que calcula el ángulo en el que la oveja intentará escapar cunado no este asustada. Veremos que cuando se asuste, huirá de un modo más eficaz.

Código :

calcularAngulo = function (oveja:String, lobo:String) {
   //
   // Calculamos la distancia en X y Y entre la oveja y el lobo
   var deltaX = _root[oveja]._x - _root[lobo]._x;
   var deltaY = _root[oveja]._y - _root[lobo]._y;
   //
   // Calculamos el ángulo en base a esas distancias
   var angulo = -Math.atan2 (deltaX, deltaY) / (Math.PI / 180) + 180;
   //
   return angulo;
};


La última función que vamos a ver por ahora, será la que nos crea los clips de película (crearlos en forma dinámica, nos permite removerlos, entre otras cosas).

Código :

crearObjetos = function (ovejas:Number, lobos:Number) {
   // Crear las ovejas
   if (ovejas != undefined) {
      for (i = 1; i <= ovejas; i++) {
         this.attachMovie ("Oveja", "oveja" + i, i);
      }
   }
   //  Crear los lobos                                                    
   if (lobos != undefined) {
      for (i = 1; i <= lobos; i++) {
         this.attachMovie ("Lobo", "lobo" + i, i + ovejas);
      }
   }
};





Bien, este es el principio, para no extenderme demasiado, voy a cortar ahora, simplemente, esperen las otras entregas, pero pueden empezar a jugar con este código. Para probarlo, yo cree 3 MCs, exportados para AS con los siguientes nombres:

Oveja
Lobo
Linea

La obeja y el lobo son simples círculos de mismo tamaño y distinto color con el punto de anclaje en el centro y la línea, es una línea vertical con punto de anclaje en su extremo inferior que mostrará el ángulo en el que escapará la oveja.


Para ver un ejemplo de lo que estas funciones hacen, he aquí el código en el que las estuve probando:

Código :

//
crearObjetos (1, 2);
//
oveja1._y = 200;
oveja1._x = 275;
//
lobo1._x = 540;
lobo1._y = 10;
lobo2._y = 290;
lobo2._x = 300;
//
lobo2._xscale = 180;
//
this.attachMovie ("Linea", "linea", 1000);
//
onMouseMove = function () {
   oveja1._x = _xmouse;
   oveja1._y = _ymouse;
   linea._x = oveja1._x;
   linea._y = oveja1._y;
   linea._rotation = (calcularAngulo ("oveja1", buscarLobos ("oveja1", 2)));
};
onMouseDown = function () {
   trace (buscarLobos ("oveja1", 2));
};


Como verán, con el mouse se mueve la oveja y al hacer click, se puede ver cómo esta detecta el lobo más cercano. El xscale, fue solo para identificar los lobos.



Bueno, eso es todo por ahora, esperen próximas entregas de Inteligencia Artificial para mayores análisis, más código y más ejemplos. Espero les sirva de algo.


Cambios relizados:
1) La parte 2 está aquí: http://www.cristalab.com/foros/viewtopic.php?p=221382#221382

2) Corregido un error, un Math.round sobraba y ocasionaba errores en la parte 2

3) Un error de tipeo, la oveja se mueve 20% más lento que los lobos cuando está tranquila, antes (por error) decía que 20% más rápido.

Por HernanRivas

Claber

3416 de clabLevel

26 tutoriales

 



Ultima edición por HernanRivas el 03 Dic 2006 05:03 pm, editado 1 vez

Argentina

msie
Citar            
MensajeEscrito el 20 Nov 2006 07:22 pm
Muy interesante de verdad.

Y es que estos son unos de los temas que a muchos principiantes desarrolladores de VG basados en flash se cuestionan.

Estaremos pendientes de las demás entregas basadas en AI.

Recuerden que esto es uno de los principios que uno debe tomar en cuenta al momento de decidirse aprender más acerca del desarrollo de VG. Esto aunado a un engine físico de detección de colisiones, bouncing y demás dan como resultado juegos más realistas y divertidos.

(y)

Por gabovanlugo

651 de clabLevel



Genero:Masculino  

Code Designer

firefox
Citar            
MensajeEscrito el 20 Nov 2006 07:45 pm
Bueno, no está nada mal para iniciarse en el mundo de la programación de juegos flash. :)

Por Sisco

BOFH

3700 de clabLevel

12 tutoriales
4 articulos

Genero:Masculino   Bastard Operators From Hell

Catalunya

firefox
Citar            
MensajeEscrito el 21 Nov 2006 07:27 pm
Genial hernan, hace nada estuve buscando por la red informacion acerca de la inteligencia artificial y no encontre nada que mereciera la pena aplicar en flash, pero aun asi decidi seguir con ello. Ahora voy a experimentar un poco con tu codigo :P

Saludos, Metal_Storm.

Por Lightwave

100 de clabLevel



 

Hyrule

msie
Citar            
MensajeEscrito el 21 Nov 2006 09:48 pm
Bueno, gracias. La idea con la que empecé este tutorial era mostrar como armar (seguro hay más maneras de hacerlo) un comportamiento que parezca inteligente. Como esta es solo la primera parte decidí comenzar mostrando algunas funciones útiles que son necesarias para armar la mayor parte de los videojuegos.

Ya estoy terminando la segunda parte y, apenas la termine, la posteo. En esa segunda parte muestro como hacer todo el código que movería a la oveja. La tercera, mostraría los lobos y las conclusiones finales.

Supuse que como muchos llegan al Flash con la intención de hacer juegos como los que ven en minijuegos (por mencionar uno) esto les vendría bien.

Me alegro de que haya servido para algo.

Por HernanRivas

Claber

3416 de clabLevel

26 tutoriales

 

Argentina

msie
Citar            
MensajeEscrito el 28 Nov 2006 12:28 am
Excelente, muy util

Por eveevans

Claber

450 de clabLevel

3 tutoriales

 

Nicaragua

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.