crear archivo de texto con resultados

Started by Futu-block, August 30, 2016, 08:26:39 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Futu-block

Vale, otra mas, estoy luchando por escribir un archivo de texto donde cada linea me guarde una coordenada de segun que objetos, y que esas coordenadas se puedan cambiar desde el mismo juego...

Mas o menos DCelso lo ha hecho en su juego de la oca, pero no lo termino de pillar por mas que me relea el codigo ¬¬

Osea, debe de buscar en la linea adecuada y dar valor a la x,y luego si yo lo modifico debe de guardarse esa coordenada en esa linea

Drumpi

Me has hecho leerme el codigo de la escalera, que lo sepas.

Bueno, resumiendo mucho, lo que hace es lo de siempre: abre el fichero con FOPEN, y va leyendo las líneas de texto con FGETS. Luego usa
http://wiki.bennugd.org/index.php?title=Split
para dividir la línea: indica que cada coma de la linea indica por dónde se debe separar la cadena, luego la cadena que debe separar (que es "line", la variable tipo string que ha usado en FGETS para obtener la línea), dónde almacenar las líneas (le manda un puntero a splitted, que es un array de strings ¡creía que no se podían usar!), y cuántas cadenas quiere que existan como máximo (porque en la oca, la cadena se puede dividir en 3 o 4, si tiene texto, pero no tengo el código para decirte exactamente cómo lo ha hecho).

Lo extraño es cómo ha almacenado todo. Entiendo que tiene un array de una variable tipo "punto" que almacena valores X e Y, concretamente 50 posiciones, que son las casillas que hay. Lo que no encuentro es la definición del tipo, sino de un proceso con ese nombre. Supongo que tendrá algo que ver con lo que hizo Splinter con el tema de las variables públicas.

Aparte de eso, es repetir el proceso con cada una de las 50 lineas. Las lineas pues las habrá escrito con el bloc de notas. Los valores los habrá sacado usando el paint para ver las coordenadas dentro del gráfico.

El tema de cómo ha añadido los textos de la oca a la información de la casilla ni idea porque no tengo el código, pero básicamente habrá creado un tipo similar a este:
type casilla
    int x;
    int y;
    string info;
end


O su equivalente con un proceso.
Sigo sin saber si eso está bien hecho o es que ha mezclado Bennu con Java :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)

Futu-block

Por fin una persona normal que no entiende algún código... Y si, era de la escalera y no la oca jiji
Pues bien, se trata de guardar en cada línea la coordenada x,y de cada proceso para luego ir a la línea correspondiente para leerlo cuando haga falta

DCelso

#18
 ;D , bien leído Drumpi, se ve que controlas taco.

Lo del type, pues no lo uso, lo que hago es usar los procesos como si fueran clases. ahí es donde meto las variables como public, mucho más cómodo para mi.

En el caso de las string de la oca, lo que hice fue eso un split de 5: 2 para poner el punto (x,y ) en pantalla, 1 para la casilla a la que salta, 2 para dos textos, en vez de uno usé dos textos para simplificar la cosa a la hora de dibujar el texto en pantalla y no se cortase.

En cuanto a guardar, no guarda nada la oca ni la escalera, tuve que hacerme una versión mía en la que se pudieran mover los puntos, tuvieran una imagen para verse y al darle al dado los guardase, plan editor de puntos cutre mio :D .

En cuanto al 50, es un máximo, no tiene que haber 50 casillas, hay una variable llamada num_casillas que guarda el número actual que lee del archivo de puntos. el 50 es para crear un array estático que usar, en vez de estar usando calloc y malloc y toa la pesca, que complican el código.

El código ha evolucionado un poco desde la escalera a la oca, pero ahora, que tengo otro a medias lo he evolucionado más, ya he separado los códigos del editor y del juego para que sean menos cutres. Y creado algunas variables globales y bucles para simplificar la cosa.

la función de guardar ahora es tal que asi, super fácil, sin usar estructuras complejas ni nada.


function guarda_punto()
private
int handle;
string line;
string splitted[2];
int n;
int i;
begin
    handle=fopen(recursoTablero[2],O_READWRITE);
    fseek(handle,0,SEEK_END);
    for (i=1;i<=20;i++)
      line =  itoa (casillas[num_casillas+i].x) + "," + itoa (casillas[num_casillas+i].y);
      fputs(handle,line);
    end
    fclose(handle);               
end

process boton(x,y)
private
  int id_mouse;
begin
    graph = load_png("recursos/boton.png");
    while (!key(_esc))
      id_mouse = collision (type raton);
      if (id_mouse)
          if (mouse.left)
                while (mouse.left) frame;end
                guarda_punto();
          end
      end
      frame;
    end   
    unload_map(0,graph);         
end


Lo hice para guardar solo de 20 en 20 casillas para ir guardando por pasos y no perder el progreso.

La clave es fseek(handle,0,SEEK_END);
lleva al final el puntero de archivo para poder simular el append de c++, (no se por qué fopen de bennu no implementa eso, sería super cómodo para estas cosa). y así guardo a partir de donde me quedé.

En el caso de futu va a ser algo más dificil. porke fseek necesita saber cuantos caracteres avazar desde el inicio, posicion actual o final.
por lo que calcular la línea a leer no va a ser tan fácil.
Normalmente para esos casos lo suyo es tenerlo todo en memoria con vectores de estructuras o lo que queras y luego guardarlo todo al final.

El acceso a archivos siempre ha sido muy crítico, por lo que siempre se aconseja limitar el acceso al mínimo, un load al principio y un save al final y punto pelota, estar leyendo y guardando constantemente en ficheros es mala opción ya que son funciones bloqueantes. Aunque hay que decir que hoy en día eso ya importa poco, tenemos aviones en vez de pc en casa por lo que es tan rápido que ni se nota :D .
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

Drumpi

Hombre, lo ideal en realidad es crearte tu TYPE en lugar de usar procesos, porque los procesos consumen muchísima más memoria, y encima son propensos a ser dibujados (aunque no tengan gráfico, el blitter debe descartarlos... aunque como dices, en PC eso es un soplido en un tornado).

Es más, puedes crearte un array simplemente haciendo:
type casilla
    int x;
    int y;
end

global
    casilla array_casillas[50];
end


y punto. Además, si quieres usar punteros, haces un mi_ptr = alloc(50 * sizeof(casilla)) y ya puedes usar la variable como si fuera un array (o casi, debes controlar no salirte del tamaño (para eso están las constantes) y acordarte de usar FREE antes de salir).

El tema de los ficheros es más peliagudo. No es el problema de las velocidades a las que se mueven los ordenadores, sino que al mantener el fichero abierto, lo dejas "bloqueado", y cualquier intento de acceso a él puede provocar desde un simple warning al otro programa, al cierre del tuyo. He tenido muchísimos problemas cuando hice "cierto editor de aventuras" por mantener los ficheros abiertos, problemas del tipo cierres del programa aleatorios. Desde que empecé a almacenar los datos en memoria, se redujeron drásticamente.
No sé si sería por un chequeo del sistema o qué (no me quiero ni imaginar los prblemas que daría un recolector de basuras).

Es por eso que el problema de usar FSEEK me parece hasta conveniente, porque lo suyo sería leer todo el contenido, cerrar el fichero, añadir los datos en la lista en memoria, y reescribir el fichero. Además, ten en cuenta que como uses los formatos de fichero comprimido (Z_READ, Z_WRITE o Z_READWRITE) no vas a poder usar FSEEK.
Si lo que te da miedo es la volatilidad de los datos en memoria, para eso se inventó el "autoguardado" (es decir, que debes crear un proceso que genere cada X segundos un fichero temporal con los datos en memoria hasta el momento).
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)

Futu-block

¿que estais diciendo, que puedo guardar los datos en un dcb donde se acceda facilmente?

La idea de guardar en un archivo de texto era para que fuera mas comodo para el tema de editarlo haciendo trampas y abriendolo en un editor de texto externo. Me seducia la idea de poder escribir un .txt sabiendo cada linea lo que representaba y ver el resultado al abrir el .dcb

Si puedo modificar varias variables dentro del mismo programa (porque no es para un juego) y luego se queda grabado en el .dcb para cuando lo abra de nuevo los datos sigan como los dejé o los reseteo

A parte que siempre puedo editar el .prg de las variables globales...
aunque luego habria que compilar y ya me falla todas las teorias...
|--------------------------------------------------------0--------------------------------------------------------|
Cambio de consulta

¿como se guardan datos dentro del .dcb para que pueda acceder a ellos cuando abra otra vez el .dcb?

DCelso

leíste muy mal, repasa.
Eso que dices de cambiar el dcb se puede hacer sí, pero no es lo que estabamos diciendo picha.

Estábamos hablando sobre un fichero de texto plano txt, siempre normal y corriente editable con el block de notas.

Mira mi .pts. de la escalera, oca o chinesenspiel. es un txt plano donde guardo por cada línea unas coordenadas x,y. que representan una casilla.

Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

DCelso

con respecto a guardar en el dcb se podría hacer haciendo lo siguiente.

Primero de todo, saber exactamente cuantos bytes ocupa tu dcb final compilado.

segundo hacer fopen read_write del dcb

tercero hacer fseek desde el inicio del fichero hasta el byte último de tu compilado.

si coincide con el final del archivo es que no había datos metidos. por lo que podríamos meter lo que quisieramos a partir de eso.
si no coincide es porque hay datos, así que podríamos empezar a leerlos a partir de ahí.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

Futu-block

si, pero estais diciendo que es un coñazo, que no se puede acceder a la linea en cuestion, que si tal...

No me parece mala idea cambiar las variables dentro del .dcb, e incluso podria programar un ''modo debug'' donde desde el mismo programa accederia a ellas y las cambiaria, la pregunta es si puedo dentro del mismo .dcb o juego/programa ejecutandose cambiar las variables para cuando abra otra vez el programa aparezcan las mismas variables con el nuevo valor

casi me seria de mas utilidad porque no se puede cambiar externamente las variables

Otra cosa que si puedo hacer es cambiar los puntos de control de las nuevas imagenes (creadas a partir de la superposicion de varias) dentro del nuevo fpg creado, ya solo si se abre el fpg nuevo se puede cambiar esos puntos de control, pero eso seria ya menos importante


Pd:
Puede que me haga falta un nuevo editor fpg mas simplon, y si se le cambia la extensión .fpg por otra mas ''confusa'' mejor

DCelso

Lo de cambiar el valor de las variables del .dcb uff, no se yo ni cómo poder encontrarlas en el archivo compilado.

La ñapa que te dije anteriormente sería añadir al final del dcb como un fichero de configuración concatenado y leerlo al ejecutarse y grabarlo al cerrarse el dcb.

Si lo que quieres es bloquear el acceso a editar los archivos de configuración desde fuera te recomiendo que los encriptes con una clave que solo tu conozcas y listo, ya quien lo abra solo verá porquería.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

DCelso

Me puse y lo hice.
lo mas importante para probarlo es:
compilar la primera vez el .prg y en la salida ver los bytes que ocupa y ponerlos en la variable

len_dcb = 54238;

luego volver a compilar y probar.


import "mod_video"
import "mod_key"
import "mod_map"
import "mod_proc"
import "mod_grproc"
import "mod_text"
import "mod_file"   
import "mod_string"
import "mod_say"

global
  int valor_x;
  int valor_y;
  int len_dcb;
begin
    len_dcb = 54238;
    set_mode(320,240,32);
    map_clear(0,BACKGROUND,RGB(0,0,1));
    cargapunto();
    puntazo();
    raton();
    loop
        frame;
        if(key(_esc)) break; end
    end                 
    let_me_alone();
    guardapunto();
end

process puntazo()
private
int collisionID;
begin
  x = valor_x;
  y = valor_y;   
  graph = map_new(5,5,32);
  map_clear(0,graph,RGB(230,230,0));
  loop
     collisionID = collision(type raton);
      if (collisionID)
         if (mouse.left)
            x = mouse.x;
            y = mouse.y;
            valor_x = mouse.x;
            valor_y = mouse.y;   
         end
      end
      frame;
  end   
  unload_map(0,graph);
end

process raton()
begin
  graph = map_new(3,3,32);
  map_clear(0,graph,RGB(230,0,0));
  loop   
      x = mouse.x;
      y = mouse.y; 
      frame;
  end   
  unload_map(0,graph);
end

function cargapunto()
private
int handle;
int i;
begin
    handle=fopen("cfgEnDCB.dcb",O_READ);
    valor_x = 200;
    valor_y = 100;
    if (not feof(handle))
      i=fseek(handle,len_dcb ,SEEK_SET);
      say (i);
      if (not feof(handle))
        fread(handle,valor_x);
        fread(handle,valor_y);
      end
    end
    say (valor_x);
    say (valor_y);     
    fclose(handle);
end

function guardapunto()
private
int handle;
begin
    handle=fopen("cfgEnDCB.dcb",O_READWRITE);
    say (valor_x);
    say (valor_y);     
    if (not feof(handle))
      fseek(handle,len_dcb,SEEK_SET);
      fwrite(handle,valor_x);
      fwrite(handle,valor_y);
    end     
    fclose(handle);
end
           


Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

Futu-block

Vale, olvidemoslo todo, ahora toca empollar la escalera hasta que lo pille, creo que vá a ser la opcion mas viable pues hay que guardar el comic en un txt o lo que sea para que se pueda editar

puedo pasar de el en el editor de caras o el editor de cuerpos

Drumpi

Olvídate del DCB porque nadie ha hablado del DCB. Yo he dicho MEMORIA, RAM, guardar el contenido del txt en unas variables del programa :D :D :D

Como dice DCelso se puede hacer eso (y creo que es más sencillo todavía, pero no sé si Splinter ha añadido el campo "tamaño" a los datos de la cabecera del DCB, como hacen otros formatos), pero también puedes añadir el TXT al DCB como "mochila". Hay una opción del compilador que te coge todos los ficheros (FPGs, MAPs, TXT y lo que te de la gana) y los autoincrusta en el DCB, de forma que cuando quieres distribuir tu juego sólo irá el runtime de Bennu (BGDI y librerías) y tu DCB.
Pero nunca lo he usado ni sé cómo va, creo que era la opción -a o algo así.

De momento te creas tu TYPE con los campos que quieras (ojo, nunca uses STRINGs dentro de un type, se puede añadir uno si es el último campo y vas a usar punteros), te creas un array de ese tipo, y los rellenas desde un fichero de texto (aunque sinceramente, prefiero un fichero binario, es más eficiente aunque más complicado de elaborar, aun usando un editor hexadecimal).
Cuando entiendas cómo lee los datos el juego de la escalera, podrás pasar a cosas más gordas.

PD: DCelso, cuidado porque el DCB varía en tamaño según la release de Bennu, las opciones de compilación y la información de debug que lleve.
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)

DCelso

Cierto, mi modo de meter detrás del dcb las variables es malísimo, mejor no usar.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/