función de path find amplificada

Started by Prg, December 28, 2008, 03:49:27 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Prg

hola, voy a estar fuera 2 días pero antes de salir quiero darlos mi regalo de navidad, como respuesta al de Splinter... je je je

bueno, hice una cosa que se carga y que te permite usar la función path find ocultando su complejidad.
el código de la función es:


EDITADO: AGREGO UNA NUEVA FUNCIÓN Y ACOMODO ALGUNOS DATOS DE LA FUNCIÓN AVANZA. TRANSFORMO LA FUNCIÓN AVANZA EN LOCAL COMPLETAMENTE.
[code language="bennu"]function avanza(fichero,grafico,x1,y1,efecto,int * arx,int * ary, *dat,velocidad,float escala);
private
   dato;
begin
   x=father.x; y=father.y;
   if (velocidad>dat[1]-1-dat[0]) velocidad=dat[1]-1-dat[0]; end
   if (velocidad<0) velocidad=0; end
   if (escala<0.25) escala=0.25; end
   if (dat[0]<(dat[1]-1) & x1==arx[dat[1]-1] & y1==ary[dat[1]-1] & father.x==arx[dat[0]] & father.y==ary[dat[0]])    //si las coordenadas no han cambiado
      dat[0]+=velocidad;
      father.x=arx[dat[0]]*escala; father.y=ary[dat[0]]*escala;

   else
      if (map_get_pixel(fichero,gráfico,x1/escala,y1/escala)==0)
         dato=path_find(fichero,grafico,x/escala,y/escala,x1/escala,y1/escala,efecto);

         if (dato)
            dat[1]=0;
            dat[0]=0;
            while (path_getxy(&arx[dat[0]], &ary[dat[0]]));

               dat[1]++;
               dat[0]++;
            end
            dat[0]=0;
         else
            return(dato);
         end

      else

         return(0);

      end


   end
   return(1);
end

function g_recta(fichero,grafico,x,y,x1,y1,escala);
private
   float ter,x2,y2;
begin
   x2=x1-x;
   y2=y1-y;
   ter=fget_angle(x/escala,y/escala,x1/escala,y1/escala);
   x2=x; y2=y;
   repeat
      angle=ter;
      x2=x2+cos(ter);
      y2=y2+sin(ter)*-1;
      x=x2;
      y=y2;
      if (map_get_pixel(fichero,gráfico,x/escala,y/escala)<>0)
         return(-361000);
      end
   until (fget_dist(x/escala,y/escala,x1/escala,y1/escala)<2);
   return(angle);
end
[/code]

su uso es:

avanza(
fichero,//del gráfico con blanco y negro
gráfico,//en blanco y negro
xdestino,
ydestino,
flags,//lo de no diag y eso
array con más de 350 espacios ejemplo: puntosx[400]),//array para almacenar los puntos x, pasarle el puntero
otro array del mismo tamaño, //para almacenar las y
array con dos dimenciones,////uso interno
velocidad,//la velocidad a la que irá nuestro proceso
escala//la que usamos en  nuestro mapa de búsquedas (ejemplo: 5 (nuestro mapa de búsqueda es 5 veces más pequeño que el real)
);


incluyo un ejemplo sencillo de un mínimo de líneas.

nos vemos en breve. :)

para el ejemplo usen la tecla u para hacerlo correr key(_u) esto es para que no se trave, pues si movemos como loco el mouse se travará, y este es un seguro.

la tecla _e sirve para verificar si se puede llegar en línea recta a un punto.

en el paquete de abajo está la función para cargarse mediante include y el ejemplo.

espero les sirva a más de alguno.

VALORES DE RETORNO DE LAS FUNCIONES:

FUNCIÓN AVANZA:

retornosignificado
0no se puede avanzar, ya sea que no hay camino o que el destino se encuentra muy lejos
1se ha avanzado

FUNCIÓN G_RECTA:

retorno                    significado
-361000no se puede ir en línea recta
algún ángulo válidoel ángulo con el que se puede ir hacia el punto en línea recta
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

SplinterGU

Muchas gracias!
Ya que andamos con los regalos ahi va un karma!
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

darío

Gracias, ya he visto preguntas de pathfinding más de una vez así que seguro que le es útil a mucha gente.

Karma +1 (tu Splinter también lo tuviste por tu regalo ;))
My sites:
Smart Fpg Editor - Painless FPG Edition for Bennu and PixTudio
fenixlib - .NET support for manipulating PixTudio, Bennu and Div graphic formats

Prg

muchísimas gracias por los karmas.
Estoy agregando una función para saber si se puede llegar a un punto en línea recta, por el momento sólo funciona si la línea es de pi/2 rad o múltiplos, sin embargo deceo tenerlo para todos los ángulos para eso de lanzar disparos. espero poderlo hacer. :)
eh corregido el hecho de que puedas mover el proceso que crea el camino y entonces busque el camino no importa que no sean las posiciones adecuadas, y he agragado algunas cositas. voy a comer, pues acabo de llegar de viaje, pero al rato subo una versión con los cambios agregados. :)
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

Prg

agregada nueva función y modificada función avanza para hacerla más útil.
:)
descarga en el primer post
a propósito, hace unas horas no podía entrar al foro. a alguno le pasó lo mismo, o sólo a mí  ??? .
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

Windgate

Es estupendo, me faltaba un modulo de estos para mi coleccion, muchas gracias.

Solo una cuestion, ¿Todavia no hay forma de incrementar la profundidad de busqueda? Aun a costa de saturar el sistema me refiero...
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Prg

:)
¿con profundidad de búsqueda te refieres a la distancia?
si es así, la única forma es hacer tus mapas de búsqueda más pequeños que los de visualización, y poner ese valor en la escala. eso es lo único que se me ocurre :)
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

Windgate

Si, esa es la solucion facil (Y la que uso por ahora...).

Me referia a si es posible editar el codigo fuente de la funcion path_find(). Supongo que se tratara de un algoritmo de busqueda en un arbol, y no creo que sea muy dificil modificar la profundidad. Quiza cambiando un simple valor numerico ZAS!

Imagino que la funcion formara parte de alguno de los DLL de Bennu, nunca me ha dado por intentar modificar un DLL, soy completamente virgen en ese sentido xD
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Windgate

He estado informándome para desensamblar el DLL de path_find, pero al ser un binario y no conocer el lenguaje original en el que fue programado debe ser cosa difícil...

Investigo tu código minuciosamente, aunque por ahora no he podido adaptar la función avanza() a mis juegos, con cambiar la escala no me ha sido suficiente. Sé que es mucho pedir pero si subes una versión con algún comentario más sería muy muy útil.

Estoy interesadísimo en el path_find y lo más útil que he visto en ese sentido es tu ejemplo, ¿Alguna versión nueva?

Ánimo que el path_find bien utilizado puede dar muchísimo juego, ya tengo en mente usar path_find para hacer un juego de "Tower Defence" llamado Corral de Mocos (Aunque por ahora es sólo un sueño :'()
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

imagino que te referis a la mod_path... bueno, aca tenes todos los fuentes de bennu...

http://bennugd.svn.sourceforge.net/viewvc/bennugd/
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Windgate

Cielo santo!!!

No sabía que estaba el fuente disponible para path_find...

http://bennugd.svn.sourceforge.net/viewvc/bennugd/modules/mod_path/mod_path.c?revision=6&view=markup

No he revisado muy a fondo el código y de hecho me iré a dormir ya mismo porque estoy medio muerto, pero no veo limitaciones en la profundidad de búsqueda... He hecho pruebas con el típico test de dibujar un laberinto y dejar que lo resuelva y resuelve laberintos de durezas de tamaño considerable (Aprox 100x100 pixels!!!).

Sencillamente estupendo, un trabajo de auténticos ARTESANOS!!!

Muchísimas gracias, veré si puedo hacer algo digno con la librería mod_path y en cuanto lo tenga lo subiré al foro, mil gracias a todos!!!!
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

izubiaurre

Me parece que en la función de PathFind de DIV2, esa profundidad era mayor. Yo trabajaba con mapas de hasta 160x120 pixeles, e incluso se podría haber heco de 320x240.

Prg

amigos, bennu es increíble, yo he trabajado con distancias de hasta más de 300 pixeles... (creo que a 340 todavía va).
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)

Windgate

Los mapas de juegos de estrategia como Starcraft o Warcraft III tienen mapas de hasta 256x256 casillas (Creo que más no...), si el path_find de Bennu es capaz de resolver más que eso es una verdadera maravilla!

Se comentó en uno de los posts en los que se hablaba de path_find que el problema es que el camino que resuelve es único, y para varios procesos simultáneos es necesario "memorizar" cada camino, y eso hay que programarlo "a mano". Había incluso un ejemplito por ahí hecho, con una función que se llamaba avanza(), ¿Alguien tiene algo hecho en esa línea?
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

acabo de probar con 256x256, probe con un mapa de 258x258, poniendo el inicio en 1,1 (0,0 parece que no va), y el fin en (257,257), y funciona a la perfeccion... eso si, segun los obstaculos que se le pongan puede tardar demasiado, y la verdad que el path resuelto no siempre es el mas corto...

si alguien se anima a hacer algo optimo y preciso, sera bienvenido...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2