Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: calio en Julio 10, 2011, 09:13:47 AM

Título: Leer escenarios externos
Publicado por: calio en Julio 10, 2011, 09:13:47 AM
Hola :)
He estado desarrollando un motor hace mucho tiempo (m?s del que me gustar?a n_nU) y he podido sortear todos los problemas que ha conllevado su realizaci?n de buena forma hasta ahora, sin embargo para el siguiente problema me veo en la necesidad de recurrir a preguntar una duda a la comunidad.
Ver?n, para hacer los escenarios estoy usando una aplicaci?n llamada Tiled. no me quejo, pues la aplicaci?n es bastante buena y muy flexible, bastante cercana a lo que yo estaba buscando. Ahora, el problema es al momento de importar los escenarios a Game Maker, pues, como uds. ya sabr?n, la lectura de ficheros de texto externos en Game Maker es muy engorrosa, y bueno, se imaginar?n que un escenario es un archivo de texto enorme n_nU
B?sicamente, mis escenarios tienen por lo menos tres capas. La primera, llamada Capa 0, es la capa de tiles estructural, donde se encuentran los s?lidos del nivel, algo as? como el nivel m?s bajo del escenario. El resto de las capas de tiles son capas donde est?n los tiles de las capas superiores, como los pisos que se pueden atravesar. Cada capa es independiente de su profundidad, es decir, la capa 0 y la capa 1 pueden tener la misma profundidad. Finalmente est? la capa de objetos, que se autodescribe.
La estructura de los escenarios que genera Tiled est? bien, pero el proceso que estoy ocupando para leer cada escenario es, por decirlo menos, incre?blemente compleja ._.
Les dejo a continuaci?n el flujo que escrib? para planear la programaci?n del sistema:

-Crear una lista
-Pasar todo el archivo a la lista
-Ubicar las propiedades, leerlas y guardarlas en una lista asignada a un arreglo unidimensional de indice nivel correspondiente.
--Alto de la room
--Ancho de la room
--Tama?o de las tiles
--Siguiente escena
--Escena anterior
--Tipo de escena
--Cantidad de capas (sin contar la 0 y la de objetos)
-Crear una room con las propiedades anteriormente rescatadas.
-Ubicar la capa 0
-Crear una malla en un arreglo bidimensional con primer ?ndice de valor nivel al que corresponde el mapa y segundo indice el numero de la capa.
-Guardar el valor de la profundidad de la capa en [nivel,0]
-Crear otra lista de profundidad alto de la room / tama?o de las tiles que contenga la info de las tiles de la fila actual
-Explotar cada ?tem de la lista en una malla con valor y de la fila actual.
-Repetir el proceso con cada fila
-Borrar la lista que se uso para la informaci?n de las filas.
-Ubicar el resto de las capas de tiles y repetir el proceso anterior
-Ubicar la capa de objetos
-Explotar cada objeto en una malla (x como nombre del objeto, y como sus propiedades en formato evento= c?digo) asignado a un arreglo de ?ndice el nivel al que corresponde
-Borrar la lista que contiene el archivo
-Borrar la lista que contiene las propiedades de la room
-Cerrar el archivo y pasar al siguiente escenario

?A alguien se le ocurre un flujo m?s sencillo? En serio que cuando escrib? el flujo para programarlo casi me muero por la cantidad de cosas que hay que hacer D: y no quiero ni pensar cu?nto se va a demorar en hacer eso para cada escenario, ni en la cantidad de memoria que va a gastar.

Eso. Un saludo :) y gracias de antemano.
Título: Re: Leer escenarios externos
Publicado por: brunoxzx en Julio 10, 2011, 03:55:44 PM
La verdad no se me ocurre nada para hacer mas f?cil la lectura de tus escenarios, tal vez si nos dejaras el archivo de tu escenario o un ejemplo, para que nos sea o al menos a mi me sea un poco mas simple idear un sistema mas r?pido que el que dices.
Título: Re: Leer escenarios externos
Publicado por: calio en Julio 11, 2011, 06:08:28 AM
Adjunto un mapa y un archivo que lee y dibuja el mapa :B todav?a no he implementado las profundidades y otras cosas. Funciona, pero f?jense en cu?nto se demora .___.
La parte que m?s toma tiempo es un ciclo que tiene tres for, uno dentro de otro, para guardar el valor de cada tile. el primer for es para las capas, y los otros dos para las coordenadas x e y. Es insano, lo se, pero as? me sali?.

http://dl.dropbox.com/u/173377/read_level.zip

Un saludo :) ojal? alguien pueda ayudarme a optimizar el c?digo .__.

PD: Qu? buen avatar, brunoxzx :p

EDIT: Creo que se me han ocurrido algunas soluciones. Ojo que ?stas soluciones son parches, pues la verdad es que me gustar?a mucho m?s que el c?digo estuviese optimizado. Las expongo ac?, s?lo por si a alguien le interesa:

1.- Crear un c?digo que parsee los mapas de antemano
?sta opci?n es sencilla, pero muy poco viable. Uno de los objetivos del motor es la simpleza para desarrollar juegos, y tener que convertir los mapas de antemano a un formato que game maker pueda leer m?s r?pido me parece una complicaci?n innecesaria. Y por qu? no, tambi?n me parece subirle la bandera blanca al c?digo :p

2.- Parsear los mapas y guardarlos en un cach?
?sta opci?n puede ser interesante. Ser?a bueno que el motor guardase la informaci?n del mapa parseada en un archivo apenas acabe de interpretarla, y que a continuaci?n en las siguientes ocasiones, utilice los archivos de cach? para leer los mapas. La gracia es que mientras esten los mapas, el motor va a poder crear un cach? de ?ste en cualquier momento en caso de desaparecer el cach? del mapa o de modificar el mapa original, volviendo el tema un proceso mucho menos engorroso. Mi principal queja con respecto a ?ste m?todo es que, bueno, crea archivos. Quiz?s para un par de mapas est? bien, pero a gran escala puede ser una mala idea.

3.- Escribir mi propio editor de mapas
?sta opci?n la descarto casi de plano. Dudo que ?sta sea la soluci?n correcta, principalmente porque el ?nico lenguaje que manejo lo suficiente como para escribir una aplicaci?n entera es GML. ?Se imaginan un editor de mapas serio que funcione sin ninguna DLL externa hecho completamente en Game Maker? Yo tampoco. O quiz?s s?, pero no puedo evitar pensar en todos los problemas que ello acarrear?a.

4.- Cargar los niveles seg?n vayan siendo referenciados.
Al principio quer?a cargar todos los niveles de una sola vez, sin embargo con el tiempo que le toma interpretar un mapa peque?o de dos o tres capas, el juego se demorar?a como diez minutos en empezar. Cargas peque?as de cinco o diez segundos entre escena y escena reci?n referenciada no es una tan mala idea, por otro lado, los tiempos de carga, por peque?os que sean, son el enemigo n?1 de todo gameplay.

Mi primera opci?n sigue siendo optimizar el c?digo, sin embargo no se me ocurre c?mo ._. si pudiese reducir esos tres loops a uno solo, quiz?s contando las l?neas y buscando de antemano la ubicaci?n de las capas, podr?a funcionar, pero honestamente no se me ocurre nada ._. y ahora debo ir a acostarme porque ma?ana tengo que despertar temprano ._.

Muchas gracias por darse el tiempo de leer mi problema :D
Título: Re: Leer escenarios externos
Publicado por: Texic en Julio 11, 2011, 02:01:20 PM
http://www.comunidadgm.org/index.php?topic=12777.0 (http://www.comunidadgm.org/index.php?topic=12777.0)
Es un poco lent?n al exportar los mapas, pero al importar es increiblemente veloz (que es precisamente lo que necesit?s). Con esto pod?s tranquilamente hacer un editor de mapas en gml (no es dificil, pero toma tiempo que deber?as dedicarle al proyecto), crear los mapas en el editor de game maker y usar el script room_export (q es bastante lento), o crear un convertidor del formato del Tiled a el formato que usa el script m?o al importar (c?digos en gml). Te recomiendo mucho la ?ltima opci?n, ser?a increiblemente eficaz y r?pida.
Bueno, al menos es lo q puedo ofrecerte por ahora, suerte!
Título: Re: Leer escenarios externos
Publicado por: calio en Julio 12, 2011, 03:18:23 AM
much?simas gracias :D leyendo y revisando

EDIT: revis? y no lo pude abrir, puesto que estoy ocupando la versi?n 7 para mac n.nU lo iba a convertir a 7 con lgm.
de todos modos, leer el c?digo del post me sirvi? para descubrir la maravillosa funci?n room_tile_add. a?n no la ocupo, pero eventualmente me servir? much?simo. ?much?simas gracias, Texic!

otra cosa, prob? una idea que me anduvo dando vueltas en la tarde; funciona de maravillas :D miren:

http://dl.dropbox.com/u/173377/read_datastructures.zip

hice que el editable anterior escribiese todas las estructuras de datos a archivos de texto, y luego program? algo que las leyese y las interpretase, con la esperanza de que fuese mucho m?s r?pido. buenas noticias: lo es :D estoy pensando seriamente en hacerlo as?. los ?nicos inconvenientes que veo es que tendr?a que ingeniarmelas para inventar una forma que compare cambios en los mapas originales (?a alguien se le ocurre una forma con GML? Se me ocurre mirar la fecha de modificaci?n o calcular el CRC, pero de ah? a que aprenda c?mo implementar un calculador de CRC en GML... ) y que los mapas pesan como 10 veces m?s que los originales. s?, el original pesa 15kb  y la copia cacheada pesa m?s de 100kb. no es un problema grave de todos modos, pero bueno.

Voy a seguir investigando :D si encuentro una forma de hacer algo tan chungo como comparar archivos y lo programo en un script, lo suelto antes que el motor :D
Título: Re: Leer escenarios externos
Publicado por: brunoxzx en Julio 13, 2011, 04:10:44 AM
Perd?n por la tardanza Calio, espero que mi c?digo aun te sirva. Se me ocurri? este m?todo para usar solo 2 fores, aunque hasta ahora no le veo mucha ventaja sobre el otro XD.

tienes que reemplazar el script explode_tiles por este.
[gml]var xx, yy, w, h;
for(current_layer=0;current_layer<=real(ds_list_find_value(properties[current_level],3));current_layer+=1){
index=ds_list_find_index(list,string(' <layer name="')+string(current_layer)+string('" width="')+string(ds_list_find_value(properties[current_level],0))+string('" height="')+string(ds_list_find_value(properties[current_level],1))+string('">'));

for(g=0;g<real(ds_list_find_value(properties[current_level],0))*real(ds_list_find_value(properties[current_level],1));g+=1){
w=real(ds_list_find_value(properties[current_level],2))
h=real(ds_list_find_value(properties[current_level],2))
xx=(g mod real(ds_list_find_value(properties[current_level],0)))
yy=(g) div real(ds_list_find_value(properties[current_level],0))
if !xx{explode("array21",",",ds_list_find_value(list,index+5+(yy)))}
room_tile_add(room_created,tileset_overcity,(real(array21[xx])-1)*16-floor(((real(array21[xx])-1)*16)/512)*512,floor(real(array21[xx])*16/512)*16,w,h,xx*w,yy*h,0)
}
}[/gml]

y hacer que en el evento create del objeto0 ya no se ejecute el script draw_tiles, tambi?n tienes que quitar lo que esta en draw que dibuja todas las tiles, y hacer que si vallas al room creado.

No es muy rapido pero estoy seguro que se puede optimizar mucho mas, por ejemplo, este c?digo estoy casi seguro de que puedes usar mods y hacerlo mas corto y mas rapido.
[gml](ds_grid_get(map_tiles[current_level,current_layer],a,g)-1)*16-floor(((ds_grid_get(map_tiles[current_level,current_layer],a,g)-1)*16)/512)*512,[/gml]

si no funciona lo de de los mods como casi todas tus multiplicaciones son en potencias de 2 puedes usar los operadores a nivel de bits ">>" y "<<", otra cosa estoy casi seguro que [gml]floor(8/3)[/gml] es lo mismo que [gml]8 div 3[/gml] y es mas r?pido.

P.D: si, lo se, mi avatar es GENIAL  :-*
Título: Re: Leer escenarios externos
Publicado por: calio en Julio 13, 2011, 05:56:55 AM
much?simas gracias :D creo que trabajar? con ?se c?digo con un par de modificaciones de caracter pr?ctico, pero la soluci?n encontrada es bastante buena :) much?simas gracias.

y muchas gracias tambi?n por el resto de los tips :)
Título: Re: Leer escenarios externos
Publicado por: brunoxzx en Julio 13, 2011, 06:54:33 AM
De nada que bueno que te sirvi? el c?digo :D y los tips.
Título: Re: Leer escenarios externos
Publicado por: Texic en Julio 13, 2011, 04:06:58 PM
Si el problema es que no los editen podr?as simplemente meterlos en included files y cargarlos desde la carpeta temporal, ser?a muy dificil para cualquier usuario modificar los mapas as?, e inclusive si los cargaras al inicio del juego y luego los borraras de la carpeta temporal ser?a imposible modificarlos.

EDIT: Si necesit?s chequear igual entonces ac? ten?s una dll que comprueba el md5 de los archivos
http://gmc.yoyogames.com/index.php?showtopic=357482 (http://gmc.yoyogames.com/index.php?showtopic=357482)
Tambi?n comprueba crc, pero s?lo de textos.
Título: Re: Leer escenarios externos
Publicado por: calio en Julio 14, 2011, 09:42:08 AM
no, justamente es para poder modificarlos :P
la idea es que si el archivo cacheado anteriormente y el archivo actual son diferentes, cachee de nuevo el mapa, para as? ahorrarse el estar borrando manualmente los caches de los mapas cada vez que se les hacen modificaciones.
pero creo que encontr? una soluci?n. hay un script que puede calcular el md5 de archivos, es lento seg?n dicen pero supongo que me puede ayudar por lo menos leer c?mo est? hecho.
supongo que estoy tratando de matar moscas a escopetazos. creo que as? era el dicho popular para resolver problemas peque?os con soluciones grandes, pero es algo que me preocupa, la idea es que si libero el motor completo -que tengo planeado hacerlo- est? dise?ado para que la mayor parte las tareas pr?cticas las haga el motor mismo, y que el motor ponga la menor cantidad de trabas posibles para dise?ar un sidescroller de aventuras.

gracias por la dll :) pero no creo que me funcione. el problema de los dll es que son s?lo compatibles con windows y yo estoy ocupando game maker para mac. ?se es un problema con el que me encuentro a menudo ._. por ejemplo, quer?a ocupar archivos .mod para la m?sica, pero todas las extensiones que leen y reproducen los archivos .mod s?lo existen para windows. es una l?stima :(

muchas gracias, de todos modos :)
Título: Re: Leer escenarios externos
Publicado por: Jiraya en Julio 16, 2011, 08:51:46 AM
aqu? un ejemplo de c?mo cargar mapas externos
download (http://dl.dropbox.com/u/34810606/Files/LoadingMapsFromMappy.rar)

mapas fueron hechos en este programa (http://dl.dropbox.com/u/34810606/Files/Mappy.rar).