Noticias

Se ha publicado un nuevo servicio, el Portal de Juegos Online

* Sponsor

Comunidad Game Maker

Bienvenid@ a la comunidad hispana de Game Maker. Nuestro objetivo es crear videojuegos y dar soporte en castellano de GM. Para mejorar nuestro servicio hemos implantado, como adicion al reglamento general, algunas normas especificas en los subforos más comunes. ¡No olvides informarte antes de participar!.

Autor Tema: Error infinite loops al intentar generar una serie de bloques [Solucionado]  (Leído 700 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Alec79

utilizo unos objetos que crean el terreno en un mapa

lo que hago es poner al inicio (obj_inicio), este al crearse, verifica si el espacio delante está vacío,
si el espacio está vacío, crea un (obj_bloque) en su posición y crea un (obj_inicio) delante, para que siga creando mas (obj_bloque) hasta que se tope con el (obj_fin)
si el espacio no está vacío, entonces se auto-destruye para que no siga creando mas objetos

esto funcionaba en game maker 8, pero al pasarlo a game maker studio me salta el error al querer correr la room
no se si me explique bien, pero les dejo el editable para que puedan ver por ustedes mismos la configuración que usé
« Última modificación: Julio 30, 2015, 12:09:29 am por Alec79 »

 


No Tienes Permisos Para Dar Puntos
point 0 Puntos

Este tema no recibió puntos.


Desconectado fasst007

Respuesta #1 en: Julio 26, 2015, 11:29:16 pm
(ANTES DE LEER: ADJUNTO PROYECTO FUNCIONANDO POR SI TE INTERESA IR DIRECTAMENTE PARA BAJARLO Y PROBARLO)

PRIMERA SOLUCION:
Dentro del objeto: "inicio", en el código del evento "create", dentro del bloque "else" vos creas dos instancias de "inicio" y deben ser de "bloque". Entonces cambia la opción object y elige: "bloque" en esas dos líneas.
También cambia el depth del objeto bloque a "-10" (u otro valor menor a cero). Y anda!!

SEGUNDA SOLUCION:
Pero de la forma anterior quedan los objetos "inicio" y "fin" existiendo debajo de los objetos "bloque" lo ideal es que estos objetos no existan más. Para ello podrías cambiar el código de la siguiente manera:

1) La primera línea correspondiente al "if" o "check object" dejarla tal cual está
2) En el primer star of block borrar lo que hay allí dentro y hacer lo siguiente:
    poner un "create instance" marcando "self", object "inicio", x: 32, y:0 y marcando "relative"
    Luego debajo poner un change_instance, elegir "self" y en change into: "bloque"

Luego en el "else" entrar al "start of a block" y borrar el código que tiene dentro y hacer:
1) Destroy instance con "self" , x:32, y:0, marcando "relative"
2) Create instance marcando "self", luego object: bloque, x:32,y:0 y "relative"
3)Luego poner un change instance: "self" y en change into: "bloque"


Listo! y nisiquiera debes modificar el depth del objeto "bloque"

ADJUNTO PROYECTO CON LA SEGUNDA SOLUCION

Saludos!
 

 

« Última modificación: Julio 27, 2015, 02:43:41 am por fasst007 »

 
Los siguientes usuarios dieron las gracias a este tema: Alec79


Desconectado Alec79

Respuesta #2 en: Julio 28, 2015, 12:19:27 am
Muchas gracias a fasst007 por ayudarme a solucionarlo :D , esto ya me tenia con dolores de cabeza, ya que como dije antes, en GM8 no daba el error :-[

 


Desconectado Alec79

Respuesta #3 en: Julio 29, 2015, 05:41:58 am
(ANTES DE LEER: ADJUNTO PROYECTO FUNCIONANDO POR SI TE INTERESA IR DIRECTAMENTE PARA BAJARLO Y PROBARLO)

PRIMERA SOLUCION:
Dentro del objeto: "inicio", en el código del evento "create", dentro del bloque "else" vos creas dos instancias de "inicio" y deben ser de "bloque". Entonces cambia la opción object y elige: "bloque" en esas dos líneas.
También cambia el depth del objeto bloque a "-10" (u otro valor menor a cero). Y anda!!

SEGUNDA SOLUCION:
Pero de la forma anterior quedan los objetos "inicio" y "fin" existiendo debajo de los objetos "bloque" lo ideal es que estos objetos no existan más. Para ello podrías cambiar el código de la siguiente manera:

1) La primera línea correspondiente al "if" o "check object" dejarla tal cual está
2) En el primer star of block borrar lo que hay allí dentro y hacer lo siguiente:
    poner un "create instance" marcando "self", object "inicio", x: 32, y:0 y marcando "relative"
    Luego debajo poner un change_instance, elegir "self" y en change into: "bloque"

Luego en el "else" entrar al "start of a block" y borrar el código que tiene dentro y hacer:
1) Destroy instance con "self" , x:32, y:0, marcando "relative"
2) Create instance marcando "self", luego object: bloque, x:32,y:0 y "relative"
3)Luego poner un change instance: "self" y en change into: "bloque"


Listo! y nisiquiera debes modificar el depth del objeto "bloque"

ADJUNTO PROYECTO CON LA SEGUNDA SOLUCION

Saludos!
la modificación sirve con una room de tamaño normal, pero por alguna razón al querer generar los bloques en un mapa mas grande, me sigue saliendo el error  :-\

dejo el ejemplo adjunto, como lo pongo no va, pero si pones la barrera de bloques para el final mas cerca, si funciona
« Última modificación: Julio 29, 2015, 05:49:12 am por Alec79 »

 


Desconectado fasst007

Respuesta #4 en: Julio 29, 2015, 07:06:38 am
Te hice un código nuevo que funciona para los bloques inicio y fin distantes.
Te adjunto el archivo fuente. Al fondo de todo está el link para descargarlo


El error me parece que es por esto:

Creo que el problema del planteo anterior no estaba en el código en sí sino en una limitación impuesta por Game Maker Studio. El código que vos habías hecho era ingenioso y con las pocas herramientas de código prefabricadas que trae GMS no había mucho margen para buscar otras alternativas. Pero te explico el por qué del error (a mi entender).

Que el código funcione perfectamente a distancias cortas pero no a distancias largas parece ilógico, pero lo que sucede es que el código genera: "recursividad" y parece ser que Game Maker Studio le puso límite a ello.

Cuando se crea el primer objeto "inicio", se ejecuta un código en su evento "create", pero el código en un momento dado crea otro objeto: "inicio" que a su vez tiene el mismo código al ser el mismo objeto. La instancia 1 de "inicio" queda en espera a que la instancia 2 de "inicio" termine de crearse para poder proseguir con las instrucciones de código, pero a su vez la instancia 2 crea una instancia 3 y debe igualmente esperar a que ésta termine de crearse para proseguir con sus instrucciones y así sucesivamente una cantidad "n" de veces.

En realidad lo que está sucediendo es que un código se llama a sí mismo porque en una parte del código "create" de una instancia crea otra ejecutando el mismo código (porque son instancias del mismo objeto). A eso se le llama recursividad. Debido a que la instancia 1 no puede proseguir la ejecución de su código hasta que la instancia 2 termine de crearse pero a su vez esta no puede proseguir hasta que la instancia 3 siga de crearse, etc. esto hace que la primera instancia "inicio" en terminar de ejecutar todo su código sea la "instancia n" (la última instancia inicio en crearse que es la que encuentra la instancia fin) cuando éste termina recién ahí puede retornar el control la instancia penúltima "n-1" y así sucesivamente hasta que el control lo tenga la primera instancia creada.

En palabras simples todas las instancias de "inicio" ejecutan su código a medias quedando en espera y recién la última instancia es la que puede ejecutar todo su código y recién ahi puede retornar a la penúltima para que termine de ejecutar su código y así sucesivamente hasta que llegue el control a la primera instancia y terminar. Pero para ello Game Maker debe ir guardando todos los datos internos necesarios para cada retorno.

Cuando se hacen muchos llamados recursivos la "pila" (que es donde se guardan los datos de retorno en una aplicación) se va llenando al almacenar tantos datos. Y pueden haber dos problemas: 1) que la pila se desborde colgando la aplicación o 2) ¿cómo sabe el compilador que esa recursividad va a tener fin? nosotros lo sabemos porque sabemos que hay un objeto fin y que finalmente lo va a encontrar, pero el compilador no tiene forma de saberlo sino es ejecutando todo el código hasta que se de el corte. Pero por precaución Game Maker Studio cuando ya se hizo una cantidad determinada de llamadas recursivas lo corta para evitar "llamadas infinitas" porque si se llamó como 50 veces y no corta (y tampoco sabe si en un futuro se va a cortar) entonces por precaución da el error.

En lenguajes de programación más potentes esto no daría error, pero Game Maker Studio al ser una herramienta de juegos para usuarios no tan avanzados no está orientada al soporte recursivo, digamos que no está hecho para eso, y por eso le da un margen pequeño a la recursividad porque es un potencial problema si no se sabe bien lo que uno está haciendo. Por eso en lenguajes más profesionales esto se permite sin tanto problema porque se supone que el programador es experto y estos temas los maneja mejor y además que el potencial que el lenguaje debe brindar debe ser mayor.

Esta explicación es una suposición mía, nada más, pero me parece que el problema pasa por ahí.
« Última modificación: Julio 29, 2015, 05:38:00 pm por fasst007 »

 
Los siguientes usuarios dieron las gracias a este tema: Alec79


Desconectado Alec79

Respuesta #5 en: Julio 29, 2015, 09:29:56 pm
Te hice un código nuevo que funciona para los bloques inicio y fin distantes.
Te adjunto el archivo fuente. Al fondo de todo está el link para descargarlo


El error me parece que es por esto:

Creo que el problema del planteo anterior no estaba en el código en sí sino en una limitación impuesta por Game Maker Studio. El código que vos habías hecho era ingenioso y con las pocas herramientas de código prefabricadas que trae GMS no había mucho margen para buscar otras alternativas. Pero te explico el por qué del error (a mi entender).

Que el código funcione perfectamente a distancias cortas pero no a distancias largas parece ilógico, pero lo que sucede es que el código genera: "recursividad" y parece ser que Game Maker Studio le puso límite a ello.

Cuando se crea el primer objeto "inicio", se ejecuta un código en su evento "create", pero el código en un momento dado crea otro objeto: "inicio" que a su vez tiene el mismo código al ser el mismo objeto. La instancia 1 de "inicio" queda en espera a que la instancia 2 de "inicio" termine de crearse para poder proseguir con las instrucciones de código, pero a su vez la instancia 2 crea una instancia 3 y debe igualmente esperar a que ésta termine de crearse para proseguir con sus instrucciones y así sucesivamente una cantidad "n" de veces.

En realidad lo que está sucediendo es que un código se llama a sí mismo porque en una parte del código "create" de una instancia crea otra ejecutando el mismo código (porque son instancias del mismo objeto). A eso se le llama recursividad. Debido a que la instancia 1 no puede proseguir la ejecución de su código hasta que la instancia 2 termine de crearse pero a su vez esta no puede proseguir hasta que la instancia 3 siga de crearse, etc. esto hace que la primera instancia "inicio" en terminar de ejecutar todo su código sea la "instancia n" (la última instancia inicio en crearse que es la que encuentra la instancia fin) cuando éste termina recién ahí puede retornar el control la instancia penúltima "n-1" y así sucesivamente hasta que el control lo tenga la primera instancia creada.

En palabras simples todas las instancias de "inicio" ejecutan su código a medias quedando en espera y recién la última instancia es la que puede ejecutar todo su código y recién ahi puede retornar a la penúltima para que termine de ejecutar su código y así sucesivamente hasta que llegue el control a la primera instancia y terminar. Pero para ello Game Maker debe ir guardando todos los datos internos necesarios para cada retorno.

Cuando se hacen muchos llamados recursivos la "pila" (que es donde se guardan los datos de retorno en una aplicación) se va llenando al almacenar tantos datos. Y pueden haber dos problemas: 1) que la pila se desborde colgando la aplicación o 2) ¿cómo sabe el compilador que esa recursividad va a tener fin? nosotros lo sabemos porque sabemos que hay un objeto fin y que finalmente lo va a encontrar, pero el compilador no tiene forma de saberlo sino es ejecutando todo el código hasta que se de el corte. Pero por precaución Game Maker Studio cuando ya se hizo una cantidad determinada de llamadas recursivas lo corta para evitar "llamadas infinitas" porque si se llamó como 50 veces y no corta (y tampoco sabe si en un futuro se va a cortar) entonces por precaución da el error.

En lenguajes de programación más potentes esto no daría error, pero Game Maker Studio al ser una herramienta de juegos para usuarios no tan avanzados no está orientada al soporte recursivo, digamos que no está hecho para eso, y por eso le da un margen pequeño a la recursividad porque es un potencial problema si no se sabe bien lo que uno está haciendo. Por eso en lenguajes más profesionales esto se permite sin tanto problema porque se supone que el programador es experto y estos temas los maneja mejor y además que el potencial que el lenguaje debe brindar debe ser mayor.

Esta explicación es una suposición mía, nada más, pero me parece que el problema pasa por ahí.

Muchas gracias por darme la explicación, nunca entedi por que es que funcionaba en  :GM8: pero no en  :GMS:
en realidad me gusta mas hacer los juegos en  :GM8: por que siento que es mas práctico por alguna razón XD
pero al querer importar el  .GMK al Game Maker Studio me salieron varios errores, la mayoría logre corregirlos, pero este en especial no entendía por que no funcionaba, bueno, te dejo el mini-proyecto en el que trabajo en mis ratos libres para que lo veas XD, en él uso el código para generar bloques para crear el mapa en la room
(me han pedido varias personas que lo porte para android, esa es la razón por la que quería que funcione en  :GMS: )

 


Desconectado fasst007

Respuesta #6 en: Julio 29, 2015, 09:40:15 pm
Felicitaciones, está bueno! llegue bien arriba y vi que hasta las nubes le hiciste!!!!!!!  :)



La idea está buena!! espero que lo termines sin problemas para android cualquier cosa consultame y trataré de ayudarte en lo que pueda
« Última modificación: Julio 29, 2015, 09:47:33 pm por fasst007 »

 


Desconectado Alec79

por si le interesa a alguien, el juego se ha avanzado bastante desde que publiqué el post, aqui el link de google play:
https://play.google.com/store/apps/details?id=com.alesso82.pixelworld


Y link al post en CGM:
https://www.comunidadgm.org/juegos-en-desarrollo/spicycandy-pixel-world/
« Última modificación: Abril 11, 2020, 08:17:20 am por Alec79 »