¿Por qué el texto no se muestra?

Started by KeiDash, November 14, 2017, 01:40:18 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

KeiDash

Me está pasando algo curioso que no termino de comprender, a ver si alguno me puede aclarar esta situación. Resulta que tengo un proceso, que cuando termina de hacer ciertas cosas, quiero que muestre un texto por pantalla. 

txt = write(0, 100, 100, 1, "Fin");

Lo que está pasando es que, con este bloque de código que muestro a continuación, si me funciona. En el, muestro justo antes de que empiece a hacer lo que tiene que hacer el proceso, el texto. En este caso, el texto si aparece. El proceso finaliza cuando presione la tecla ENTER como se puede ver, mientras, continúa ejecutándose.


Process Test(int milis, int posx)
Private
int f = 0;
int txt = 0;
End
Begin

frame;

        //ESTA ES EL TEXTO A MOSTRAR, AQUí SI SE VE:
txt = write(0, 100, 100, 1, "Fin")

While(f <= milis)
f++;
frame;
End

f = 0;

While(f <= maxYposition)
f++;
frame;
End

Repeat
frame;
Until(key(_ENTER))

delete_text(txt);

End


Ahora, lo hago como quiero que suceda, es decir, el texto solo debe aparecer cuando finalice lo que hace el proceso internamente, es decir, justo después del último While. Pues si lo hago así, el texto no se ve, pero lo curioso es que hasta que no haga clic en ENTER, no se cierra que es como debe de ser, pero como comento, el texto no se ve:


Process Test(int milis, int posx)
Private
int f = 0;
int txt = 0;
End
Begin

frame;

While(f <= milis)
f++;
frame;
End

f = 0;

While(f <= maxYposition)
f++;
frame;
End

        //ESTA ES EL TEXTO A MOSTRAR, AQUí NO SE VE:
txt = write(0, 100, 100, 1, "Fin");

Repeat
frame;
Until(key(_ENTER))

delete_text(txt);

End


¿Alguién me puede ayudar y explicarme que estoy haciendo mal o dónde está el error?

En caso de que no lo entendáis ¿Qué estoy intentando hacer en este proceso?

1) Ejecuto frame en primera intancia, para que los otros procesos del padre continuen y no esperen a que este proceso finalice. Esto lo hago por que este mismo proceso se llama varias veces, cada uno como procesos independientes.

2) Pongo un tiempo de espera en el primer While pasando un contador (milis)

3) En el segundo While, hago un contador para relizar un proceso en el que se desplaza un "sprite", de momento no está implementado, solo hago el incremento.

4) Aquí debería mostrarse el texto una vez finalice el While anterior (3).

5) Hasta que no se haga click en la tecla ENTER, el proceso sigue funcionando.

6) Borramos el texto "txt"

Llevo 3 días con esto y no lo comprendo. Indicar que el padre no está finalizando a su hijo, es más, el padre dispone de un Loop frame; End al final para que no finalice.

Por si hay alguna duda, pongo el código del padre:

Function FatherTest()
Private
int counter = 0;
End
Begin

for(counter = 0; counter <= 1; counter++)
Test(200, counter * 10);
end

While(SON != 0)
frame;
End

say("Step");

Loop
frame;
End

say("Saliendo de hijo");
End


Gracias,

Arcontus

Buenas KeiDash,

lo primero de todo y lo que me parece más llamativo es esta frase:

Quote from: KeiDash on November 14, 2017, 01:40:18 PM
Indicar que el padre no está finalizando a su hijo, es más, el padre dispone de un Loop frame; End al final para que no finalice.

Un proceso padre no finaliza la ejecución de sus procesos hijos a excepción del uso de ciertas señales (signals), así que este problema no es el tuyo.

Lo segundo que me ha llamado la atención de tu código es este for:


Function FatherTest()
...
   
   for(counter = 0; counter <= 1; counter++)
      Test(200, counter * 10);
   end
...


En este caso no es habitual construir la condición del for con un "<=", normalmente se utiliza solamente el simbolo "<". Independientemente, tal y como esta construido la condicion se cumple 2 veces (la vuelta counter = 0 y counter = 1). Sospecho que en milisegundos no deseas recibir 0 (o si), tenlo muy en cuenta y tambien sospecho que no deseas lanzar el proceso Test 2 veces, ya que write sobreescribe en el mismo lugar de pantalla el resultado (feo) y no sabes cual es cual.

Por último, tienes una condición while que no se puede saber cuando es cumplida:


...
   While(f <= maxYposition)
      f++;
      frame;
   End
...


¿Que es maxYposition? Sospecho que tu problema viene de ahí.

Espero haberte ayudado,
Un saludo.
5Leaps, el primer juego comercial desarrollado para BennuGD. http://www.5leaps.com

KeiDash

Gracias por tu respuesta Arcontus

Con respecto a los dos primeros puntos, si tienes razón, pero simplemente estoy realizando pruebas. Si es cierto que el padre nunca cierra al hijo, ya que no hay ningún signal(id, S_KILL) o algo por el estilo, pero me refería a que no hay algún proceso que esté deteniendo a el hijo para que el texto no pueda salir.

Con respecto al segundo punto, si tienes rarón, el texto se puede sobrescribir en pantalla, pero como te comento, son pruebas, lo mismo me da ahora mismo < o <=, ya salga una, dos veces o n veces.

Con respecto a lo de que posiblemente pueda ser el While(f <= maxYposition) lo que esté bloqueando el proceso, te comento que no es esto, porque maxYposition es una constante (que no añadí aquí en el código) que vale 300. Entonces, hasta que f no valga 300 eso sigue ahí dando vueltas.

La cosa es que he hecho pruebas poniendo, para ver si es que como tu dices, no salía del bucle, un say("") justo después de ese While, y se ejecutaba correctamente cuando el bucle terminaba, pero sigue sin mostrarse el texto.

Así que sigo con el mismo problema x'D

FreeYourMind

prueba poner un frame despues:


//ESTA ES EL TEXTO A MOSTRAR, AQUí NO SE VE:
txt = write(0, 100, 100, 1, "Fin");
frame; 
Repeat
frame;
Until(key(_ENTER)

KeiDash

Quote from: FreeYourMind on November 15, 2017, 06:41:26 AM
prueba poner un frame despues:


//ESTA ES EL TEXTO A MOSTRAR, AQUí NO SE VE:
txt = write(0, 100, 100, 1, "Fin");
frame; 
Repeat
frame;
Until(key(_ENTER)

Hola Free,

Eso ya lo he hecho pero no funciona. Un dato curioso que he visto es que si coloco entre medio del bloque de código llamadas a say(), el texto si aparece, pero no siempre, es algo un tanto raro y tengo la última versión de BennuGD

FreeYourMind

Prueba quitar el repeat:

//ESTA ES EL TEXTO A MOSTRAR, AQUí NO SE VE:
txt = write(0, 100, 100, 1, "Fin");

loop

if (
key(_ENTER)
break;

frame;
end


Arcontus

Con el código que muestras todo parece estar correcto, por lo que te diría chorradas como que revisa que tu resolución sea superior a 100x100 o que no tengas el fondo blanco y por ello no veas las letras. Entiendo que todo eso no puede ser, asi que me inclino a pensar en que debe ser otra parte del codigo que sin darte cuenta afecta a este proceso de alguna manera.
¿Puedes subir el codigo completo para poderse ejecutar? Creo que es la unica manera de ver el problema.

Un saludo!
5Leaps, el primer juego comercial desarrollado para BennuGD. http://www.5leaps.com

Drumpi

Pues sí que es raro, sí. Si no fuera tan tarde te lo debugearía yo mismo, porque me tiene intrigado.
Lo único que puedo hacer es darte consejos:
- Supongo que es lo que has dicho, pero pon SAY con algún mensaje tonto antes y después de cada bucle, y sobre todo, antes y depués del WRITE en cuestión.
- Usa el SAY para ver que realmente se está incrementando el contador dentro del bucle. Te podrías llevar una sorpresa.
- Prueba a hacer el write en la posición (5,5), una posición que se va a ver sí o sí, en cualquier resolución con cualquier alineamiento. Prueba a cambiar de color antes de llamar a write.
- Usa la ventana de debug: comprueba que los procesos existen, que están ahí, ejecutándose.

Son cosas muy simples, muy tontas, pero no sabes lo útil que es ir siguiendo una metodología así con un bug muy puñetero. Dar por sentadas las cosas (como que el contador está contando) es el mejor aliado de los errores de programación. Ya nos contarás.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

KeiDash

Hola chicos,

Al final lo he resuelto, pero no tengo muy claro cuál es el problema. He vuelto a rehacer el código y lo he solventado.

Es curioso pero no veo exactamente dónde está el problema, eso sí, me he dado cuenta de una cosa. Pongo el código para que veáis y me digais si vosotros veis algo raro. El resumen, es que hay un proceso que está haciendo que no me deje hacer el write a posterior (SetPoints()) como estaba intentando hacer. Voy a poner el código tal cual me está funcionando ahora:

Ver el código en Gits, en caso de que alguien lo quiera ver más claro.


import "mod_video"
import "mod_screen";
import "mod_text"
import "mod_key"
import "mod_string"
import "mod_proc"
import "mod_say"
import "mod_map"

GLOBAL
byte g_iFinish = false;
byte g_bDEBUG = false;

int g_iWidthRES = 640;
int g_iHeightRES = 480;

//Fuentes
int fntDef = 0;
int fntDig = 0;
//FpgFiles
int mainFpg = 0;
int gameFpg = 0;

//Propias de iGame
int g_iMinGotcha = 348;
int g_iMaxGotcha = 356;
int g_iGotcha = 340;
int g_iSpeed = 1;
int g_iWait = 2;
int themes[6][3];

//Game items
int g_iPoints = 0;

//KeyPositions
byte chordDL = 1; //Down Left
byte chordDC = 2; //Down Center
byte chordDR = 3; //Down Right
byte chordUL = 4; //Up left
byte chordUR = 5; //Up right
byte chordSC = 6; //Scract

END

CONST
maxYposition = 350;
END

Process Main()
Private
byte p_bContinue = 0;
int t = 0;
End
Begin

CloseGame();

RunGame(1);

Loop
frame;
End

End

Process CloseGame()
Private
End
Begin

Repeat
frame;
Until(key(_ESC))

exit();
End

Process RunGame(byte sg)
Private
int prc_Points = 0;
End
Begin

g_iWait = 0;
put_screen(gameFpg, 7);

Load(sg);

Play();

While(g_iFinish != 1)
frame;
End

//ESTE ES EL TEXTO QUE QUIERO QUE SALGA CUANDO TERMINE TODO EL PROCESO
write(0, g_iWidthRES/2, g_iHeightRES/2, 1, "TERMINO");

Loop
frame;
End

End

Process Play()
Private
int songs = 0;
int chords = 0;
int counter = 1;
byte steps = 5;
End
Begin

//OJO CON ESTE WRITE_VAR
write_var(fntDig,500,420,0, g_iPoints);

for(songs = 0; songs < 1; songs++)
for(chords = 0; chords <= steps; chords++)

Show(themes[chords][0], themes[chords][2]);

frame;

end
end

While(SON != 0)
if(SON.finalice == 1) signal(SON, S_KILL); end
frame;
End

g_iFinish = 1;

End

Process Show(int milis, byte chordID)
Private
int count = 0;
int keyPress = 0;
End
Begin

While(count <= milis)
count++;
frame;
End

FILE = gameFpg;
GRAPH = chordID;
X = chordID;
Y = 0;
Z = 97;

While(Y <= maxYposition)

Y += g_iSpeed;
X = X;

chordYPosition = Y;

If(Y >= maxYposition) break; End

frame;
End

finalice = 1;

End

//OJO CON ESTE PROCESO
Process SetPoints()
Begin
Loop
write_var(fntDig,500,420,0, g_iPoints);
frame;
End
End




Este código funciona. El Proceso RunGame, ejecuta una serie de elementos. Uno de ellos es el Proceso Play. Mi intención es que cuando el Proceso Play y sus procesos hijo finalicen, se muestra un texto en pantalla, es decir:

1) Se ejecuta RunGame
2) RunGame, pone un fondo de pantalla (put_screen), carga un array de datos (Load(sg)) y ejecuta Play().
3) Hasta que Play no termine (While(g_iFinish != 1)...) se ejecuta el bucle.
4) Cuando termin el bucle (3), se muestra el texto que quiero.

Este proceso es correcto y funciona. Ahora, si hago lo siguiente, es cuando el texto deja de mostrarse, explico los pasos para que se me entienda:

1) Se ejecuta RunGame
2) RunGame, pone un fondo de pantalla (put_screen)
3) RunGame ejecuta el proceso SetPoints() (es simplemente un bucle que hace un write_var de la variable g_iPoints
4) RunGame() carga un array de datos (Load(sg)) y ejecuta Play().
3) Hasta que Play no termine (While(g_iFinish != 1)...) se ejecuta el bucle
4) Cuando termin el bucle, se muestra el texto que quiero.

Este caso, al añadir la llamada a SetPoints(), ya el texto no se muestra, no se qué está mal con este Proceso la verdad pero es el que hace que no se muestra el texto. Pongo código actualizado para que se vea:

Process RunGame(byte sg)
Private
int prc_Points = 0;
End
Begin

g_iWait = 0;
put_screen(gameFpg, 7);

SetPoints(); //NUEVA LLAMADA

Load(sg);

Play();

While(g_iFinish != 1)
frame;
End

//ESTE ES EL TEXTO QUE QUIERO QUE SALGA CUANDO TERMINE TODO EL PROCESO
write(0, g_iWidthRES/2, g_iHeightRES/2, 1, "TERMINO");

Loop
frame;
End

End

Process Play()
Private
int songs = 0;
int chords = 0;
int counter = 1;
byte steps = 5;
End
Begin

//OJO CON ESTE WRITE_VAR
//write_var(fntDig,500,420,0, g_iPoints);
        //COMENTO ESTA LíNEA, QUE LO QUE HACE ES LO MISMO QUE SETPOINTS() pero sin llamar al proceso.

for(songs = 0; songs < 1; songs++)
for(chords = 0; chords <= steps; chords++)

Show(themes[chords][0], themes[chords][2]);

frame;

end
end

While(SON != 0)
if(SON.finalice == 1) signal(SON, S_KILL); end
frame;
End

g_iFinish = 1;

End



Como se puede ver, la única diferencia es que en RunGame llamo a SetPoints() y en Play(), comento la línea que hace lo mismo que SetPoints(), pero en diferente bloque de código.

No se...no entiendo que es lo que pasa la verdad...

Comentarios?? x'D

Gracias,

SplinterGU

simple, no funciona por son demasiadas llamada a write...

cada write crea un objeto, los objetos tienen limite... no puedes crear y crear eternamente... en algun momento se llena la cantidad maxima de textos y no va a crear mas...

si haces un write_* tienes que poner un delete_text

asi


wid = write_....

frame;

delete_text(wid);


tambien lo ideal es poner los write fuera de los loops, no es necesario repetir write cada vez para imprimir algo, solo pones write y este existira hasta que lo borres o el programa finalice... (los write_var se actualizan constantemente, pero solo necesitas crear 1)
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

#10
te marco lo que esta mal a primeras, (no se si tienes algo igual en otro lado... revisalo...)


//OJO CON ESTE PROCESO
Process SetPoints()
Begin
Loop
write_var(fntDig,500,420,0, g_iPoints);
frame;
End
End


debe ser



global
int setPointsTextId;
end

Process SetPoints()
Begin
        if ( setPointTxtId != 0 ) delete_text( setPointTxtId ); end
setPointsTxtId = write_var(fntDig,500,420,0, g_iPoints);
End


en el caso, ni necesitas hacer loop/frame
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

KeiDash

Quote from: SplinterGU on November 16, 2017, 05:56:29 PM
te marco lo que esta mal a primeras, (no se si tienes algo igual en otro lado... revisalo...)


//OJO CON ESTE PROCESO
Process SetPoints()
Begin
Loop
write_var(fntDig,500,420,0, g_iPoints);
frame;
End
End


debe ser



global
int setPointsTextId;
end

Process SetPoints()
Begin
        if ( setPointTxtId != 0 ) delete_text( setPointTxtId ); end
setPointsTxtId = write_var(fntDig,500,420,0, g_iPoints);
End


en el caso, ni necesitas hacer loop/frame

Vaya! Claro tienes toa la razón del mundo, estaba enfrascado en todo lo demás que no me daba cuenta de que estaba pasando, pero tiene todo el sentido del mundo -_-

Muchas gracias por la ayuda a todos y gracias a Splinter por encontrar el error que estaba comentiendo!

Que haría yo sin este foro :'D

Drumpi

¿Qué ha sido del mítico mensaje "demasiados textos en pantalla"? ¿Ya no sale?

Era un clásico de los errores que soltaba la consola desde tiempos de DIV ¿Quién ha sido el berzotas que lo ha eliminado?
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

SplinterGU

Quote from: Drumpi on November 17, 2017, 12:17:06 AM
¿Qué ha sido del mítico mensaje "demasiados textos en pantalla"? ¿Ya no sale?

Era un clásico de los errores que soltaba la consola desde tiempos de DIV ¿Quién ha sido el berzotas que lo ha eliminado?

dime si con esto respondo tu pregunta...


if ( textid == MAX_TEXTS ) return 0; // error ("Demasiados textos en pantalla") ;


;)

una de las cosas que hice en bennugd, es hacerlo a prueba de cancelacion por fallos... o mejor dicho, reducir la cantidad de cosas que hacen abortar la ejecucion del programa, en los casos donde se puede recuperar el procesamiento...

en los casos de demasiados textos en pantalla, como ves, retorna 0 como identificador.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Drumpi

¡Pero Bennu sin demasiados textos en pantalla es como un bebé sin chupete! Una mañana de Domingo sin Sol. Como una pradera sin cesped. Como un Mario sin su Sonic...

(Sabes que estoy de broma ¿no? :D)
PD: de paso, que sepas que has arruinado mi tira cómica nº 6 o la 7 :D :D :D
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)