Febrero 19, 2015, 10:04:58 PM Ultima modificación: Febrero 19, 2015, 10:09:13 PM por ReloadedK
Hola, antes que nada, me presento porque este es mi primer post. Me gusta esta comunidad, me ayudó a solucionar unos cuantos problemas en el pasado con temas que van desde instalar .dll hasta crear scripts.

Ahora voy directo al tema, hace mucho vi un engine que se llamaba, si mal no recuerdo, "Day and night engine v2.0", y me gustó tanto que lo quise implementar a mi propio juego.
El problema es que usaba tiles, y después de un tiempo decidí que todos los tilesets formaran parte de una carpeta externa (guardados en .png, cada room con su fondo) y la forma que elegí de cargarlos fué con la función "sprite_add", lo cual funcionó muy bien hasta ahora.
El problema es que el juego muy de vez en cuando tiene bajones de fps (cambiando de room, porque me aseguré bastante bien de que no haya lag de ninguna forma mas allá de eso), y la función me da como error "-1", indicando que no se cargó correctamente.

Si sirve de algo, comparto el código que utilizo (bastante lineal, por cierto):

Evento "Create" y "Room start":
[spoiler]
x=0
y=0

//Story
if (room)= rStory1{
    global.spritee1=sprite_add(working_directory+"/Backgrounds/InsideFront/01.png",1,false,false,0,0)}
//Tutorial
if (room)= tutorial1{
    global.spritee1=sprite_add(working_directory+"/Backgrounds/World0/01.png",1,false,false,0,0)}
if (room)= tutorial2{
    global.spritee1=sprite_add(working_directory+"/Backgrounds/World0/02.png",1,false,false,0,0)}
if (room)= tutorial3{
    global.spritee1=sprite_add(working_directory+"/Backgrounds/World0/03.png",1,false,false,0,0)}

sprite_index=global.spritee1
[/spoiler]

Evento "Step":
[spoiler]
if global.enableEffects[0]=1 or global.enableEffects[1]=1 or global.enableEffects[2]=1{

if !instance_exists(dn_controller){
if fps!=0 {
image_blend=c_white
break}
}
if instance_exists(dn_controller){
if fps!=0 {
image_blend=draw_get_color()
break}
}

}

[/spoiler]

Busco la manera de poder hacer que, en caso de que la función sprite_add devuelva "-1", por lo menos, que lo cargue un momento después. Otra solución menos vistosa sería que el sistema se resetee al cambiar de room, así aunque sea se arregla hasta cierto nivel.
Una idea que se me ocurrió es pre-cargar a todos los fondos con un objeto general, pero todavía no lo implementé y tengo mis dudas.

PD: Acuérdense que estoy cargando fondos .png de 800*600. Esta es la razón por la que a veces no se carga y se queda en "global.spritee1=-1".
Desde ya, muchísimas gracias por leer y tomarse el tiempo de ayudarme, lo estimo mucho.

#1 Febrero 19, 2015, 10:25:47 PM Ultima modificación: Febrero 19, 2015, 10:27:47 PM por penumbra
Se podrían idear unos cuantos métodos para cargar las imágenes en caso de error. Lo que me parece mejor es usar un ciclo. También se podría con alarmas, pero eso implica esperar más tiempo, aunque lo ideal sería conocer el motivo exacto por el cual a veces una imagen se carga y a veces no lo hace.

Cita de: ReloadedK en Febrero 19, 2015, 10:04:58 PM
PD: Acuérdense que estoy cargando fondos .png de 800*600. Esta es la razón por la que a veces no se carga y se queda en "global.spritee1=-1".
¿La razón es que son de 800X600? No entiendo a qué te refieres

en ROOM START
[gml]
x=0
y=0
global.spritee1 = -1
               
while (global.spritee1 == -1)    //Mientras no se cargue correctamente...
{
     //Story
     if (room)= rStory1{
         global.spritee1=sprite_add(working_directory+"/Backgrounds/InsideFront/01.png",1,false,false,0,0)}
     //Tutorial
     if (room)= tutorial1{
         global.spritee1=sprite_add(working_directory+"/Backgrounds/World0/01.png",1,false,false,0,0)}
     if (room)= tutorial2{
         global.spritee1=sprite_add(working_directory+"/Backgrounds/World0/02.png",1,false,false,0,0)}
     if (room)= tutorial3{
         global.spritee1=sprite_add(working_directory+"/Backgrounds/World0/03.png",1,false,false,0,0)}
}
sprite_index=global.spritee1[/gml]

Eso haría que el ciclo se ejecutara recursivamente hasta que por fin se cargara la imagen en cuestión, creo.

#2 Febrero 19, 2015, 10:38:10 PM Ultima modificación: Febrero 19, 2015, 10:55:12 PM por ReloadedK
Mmm, no se me había ocurrido hacerlo de esa forma, en cualquier caso, me gustaría saber a lo que te referís con "lo mejor sería hacer un ciclo".
Acabo de probar tu teoría:
El juego funcionó en un primer momento, pero después crasheó al cambiar de room, lo que me dejó bastante sorprendido.
Ahora mismo estoy probando variables a tu idea, si descubro algun dato lo coloco acá.
EDIT: Funciona igual que antes, la diferencia es que ahora cada vez que da -1 el juego crashea >.<

El ciclo es el while que penumbra dejó como ejemplo.

No encuentro errores en el algoritmo, sólo se me ocurre que el error es porque las imágenes tienen algún dato corrupto, o el error está en otra parte del código.

En el evento Step, no entiendo porqué comparas el valor de "fps", yo lo cambiaría de esta forma y debería funcionar igual:
[gml]
if( global.enableEffects[0] or global.enableEffects[1] or global.enableEffects[2] )
{
    if instance_exists( dn_controller ) image_blend = draw_get_color();
    else image_blend = c_white;
}
[/gml]

#4 Febrero 20, 2015, 03:29:18 AM Ultima modificación: Febrero 20, 2015, 03:48:03 AM por penumbra
No sé a que se deba el fallo, no me parece que el ciclo sea el problema. Sólo atino a pensar que hay algo malo en las imágenes, como dice clamud, o en la carga. Pareciera como si una vez que la función sprite_add falla, las siguientes ocasiones también fallara irremediablemente. Se le puede imponer un límite al ciclo while, o caabiar de ciclo a un for o repeat, para que sólo lo intente pocas veces.

Hay alternativas, desde luego, más allá de usar ciclos,  pero lo más importante es saber por qué la carga falla, o cuáles son las condiciones que hacen fallar a GM. Si el archivo existe y la ruta es correcta, no debería fallar NUNCA. ¿Qué editor usas para crear los fondos PNG?Yo probaría a usar un editor distinto para guardar las imágenes en formato PNG. Quizás el editor esté guardando el PNG con una opción que provoca el fallo. ¿Te has fijado si falla con una imagen en particular o si falla con las tres? También probaría a cambiar de formato y ver si con otro hay o no falla.

Muchisimas gracias a los 2 por ayudarme hasta ahora, noto una mejoría en cuanto a la velocidad de carga de las imágenes, y funciona bastante bien.

(A Clamud): Tu código en step alivió un poco la carga, disculpá mi desorden a la hora de codear.

(A penumbra): El ciclo funciona bien, y tenés razón en "Pareciera como si una vez que la función sprite_add falla, las siguientes ocasiones también fallara irremediablemente.", porque eso es lo que pasa. Chequeé las imágenes y tambien funcionan perfectamente, pero creo que hay 2 detalles que me olvidé de mencionar y que quizá puedan ayudar:

1) Para testear si hay errores, mi juego utiliza un modo debug en el cual chequeo los fps y hago que el "jugador" se mueva a las coordenadas x,y del mouse. Esto lo utilizo para ir rápido de un sitio a otro, entre otras cosas.
Mi juego va por rooms, y cuando el "jugador" llega al final de la pantalla (digamos x>=790) se ejecuta un código con el cual éste aparece en otro room en las coordenadas x=10. Lo que hago es forzar la carga para cambiar los rooms y ver hasta qué punto se llega a laguear.

2) Mi juego no utiliza la función game_restart(), éste abre directamente un .txt con coordenadas guardadas. No sé si eso afecte a la carga de sprites.

Espero que mas o menos se entienda, de no ser así me siento a explicarlo más a detalle.