¿alguien que sepa orientarme?
Hago un FOR para averiguar si cada casillero (cada N pixeles formando un tile) es un color u otro pero tarda una barbaridad, asi que he decidido que me escriba los resultados en un archivo txt o lo que sea, luego yo copio-pego al programa original y ¡¡zasca!!
pero no tengo ni idea de como se crea un archivo como este o de como se consulta, en la biblia si aparece no se donde porque no se como buscarlo, si por crear archivos, guardar textos...
una aiuda plis
Creo que lo que estás buscando es:
INT FOPEN (STRING, INT)
INT FPUTS (INT, STRING)
INT FCLOSE (INT)
private
int fileHandler;
end
begin
fileHandler = fopen("myfile.txt");
fputs(fileHandler, "This is a text");
fclose(fileHandler);
end
exactamente eso, gracias Darío, ya sé por dónde buscar
Karma++
bueno, despues de media hora de espera me ha salido rana...
La idea es que diera el valor de una variable y me ha puesto el nombre de la variable
¿alguien sabe como hacer para que me escriba el valor de la variable en vez de un string?
La idea es copiar los valores o los resultados de varias variables
-----------edito------------
al parecer funciona si no pongo entre comillas el texto:
fputs(fileHandler, variable);
Si te ha puesto el nombre de la variable es porque habŕas escrito el nombre de la variable entre comillas :)
Puedes usar la funcion itoa() para convertir el dato numerico en texto. Lo almacenas en una string y luego escribes ese string en el archivo de texto. Recuerda que fputs() siempre te añade un salto de linea cuado escribes un string en el archivo, por lo que cada vez que escribas con fputs lo hara en lineas diferentes.
Guay, tu primer karma, newbie
Ahora me toca implementarlo de alguna manera que cree un archivo que me codifique una instrucción para luego consultarla cada vez que quiera o crear nuevas
Yo tengo un invento que igual te viene bien.
ini_read.pr-:
Global
string loaded_ini_data;
End
Function load_ini(string ruta);
Private
string linea;
Begin
loaded_ini_data=file(ruta);
end
Function string read_ini(string seccion,string clave);
Private
string datos;
int pos_seccion;
int pos_siguiente_seccion;
int pos_igual;
int pos_principio_clave;
int pos_final_clave;
Begin
if((pos_seccion=find(loaded_ini_data,"["+seccion+"]"))>-1) //buscamos el principio de la sección
pos_siguiente_seccion=find(loaded_ini_data,""+chr(10)+"[",pos_seccion); //averiguamos dónde empieza la siguiente sección
if((pos_principio_clave=find(loaded_ini_data,""+clave+"=",pos_seccion))>-1) //buscamos la clave siguiente con ese nombre
if(pos_siguiente_seccion==-1 or pos_principio_clave<pos_siguiente_seccion) //que se encuentre en esa sección
pos_final_clave=find(loaded_ini_data,chr(13),pos_principio_clave); //msdos, \r
pos_principio_clave+=len(clave)+1; //detrás del =
datos=substr(loaded_ini_data,pos_principio_clave,pos_final_clave-pos_principio_clave);
end
end
end
return datos;
end
Function read_ini_int(string seccion,string clave,int defecto);
Private
string datos;
Begin
datos=read_ini(seccion,clave);
if(datos=="")
return defecto;
else
return atoi(datos);
end
end
Aunque... me acabo de dar cuenta de que no hice las rutinas generales para escribir nuevos datos xD
Puedes ignorar mi aporte a medias, o terminarlo... xD
de eso nada monada, es muy interesante para estudiarlo y para (lo mas importante) comprenderlo...
de todas formas, estoy tratando de construir un ejemplo de lo que quiero exactamente, pero lleva tiempo...
(y la crap 666 a la vuelta la esquina)
Si lo que quieres es guardar muchos datos juntos, que siempre van a estar en el mismo orden, puedes crear una variable de tipo compuesto, como:
type data_guardar
int n_jugadores;
word puntos[4];
int max_nivel;
end
Luego, en el juego creas una variable de este tipo y la rellenas con los datos:
private
data_guardar var_guardar;
begin
var_guardar.n_jugadores = 2;
var_guardar.puntos[0] = 100;
var_guardar.puntos[1] = 85;
var_guardar.max_nivel = 10;
(...)
Así, con "save("save/partida.sav", var_guardar)" guardarás todos los datos en un fichero, y con "var_guardar = load("save/partida.sav")" puedes cargarlos. Mírate la sintaxis porque no sé si es la correcta, porque son funciones que no suelo usar. Y no utilices strings porque con ese tipo de variables suele haber problemas.
Si no, usando FOPEN y FCLOSE: tienes FPUTS y FGETS para añadir texto al fichero, y FREAD y FWRITE para ir almacenando variables sueltas (incluso tipos definidos por ti, como he explicado antes).
Tenía un tutorial escrito por ahí, creo, pero no lo encuentro (demasiados años hace ya). Si no, mírate el manual de Osk, que seguro que hay un capítulo dedicado a los ficheros.
Aunque no lo parezca, me leo la Biblia...
Hace poco descubrí los macros y molan, jajajaj
En cuanto al texto, la idea básicamente es poder guardare una codificación en un archivo para que se pueda acceder a él y/o modificarse, algo en plan validación
Pues nada, solo necesitas conocer esos ocho comandos para escribir en ficheros, lo demás ya depende de qué quieres guardar y en qué formato.
Unas cosillas:
- Puedes usar los formatos comprimidos (O_ZREAD, O_ZWRITE en FOPEN) para "codificar" tus ficheros y que no sean legibles con el bloc de notas o un editor hexadecimal, pero si quieres meterles más seguridad: http://wiki.bennugd.org/index.php?title=Mod_crypt
- Añádele una cabecera a tu fichero: tres letras que identifiquen el tipo de fichero que estás usando (hay quien usa 8 y quien usa 12). Parece una tontería pero hay programas que lo usan para identificar el tipo de fichero (Linux antiguamente, por ejemplo), y a ti te puede venir bien en el futuro para lo mismo.
- No te ovides de añadir un campo con el número de versión. Créeme, cuando hagas modificaciones y cambies el formato del fichero te va a ser tremendamente útil para leerlos o convertirlos a la última revisión.
Esto no se ha acabao toavia...
Quiero escribir una variable en pantalla, pero quiero hacer selección en esa variable (o colisión en un cuadro invisible donde pinta la variable) y poder modificarla con el teclado...
¿Como escribo un valor nuevo en una variable a traves del teclado? Por supuesto que nada de letras, solo valores numericos
¿Te refieres a crear un cuadro de texto donde el usuario escriba una cifra?
En ese caso recomiendo crear un proceso con la imágen de la zona de texto, capaz de decirle al sistema "oye, que el ratón ha hecho clic en mi, dame el control que tengo que recibir datos del usuario", y usar la variable global ASCII para leer los caracteres del teclado.
El algoritmo ya se subió al foro, tendría que volver a buscártelo, pero estaba adaptado a todo tipo de texto. Como usaba un SWITCH para saber si se había seleccionado un caracter, el botón de borrar, o el botón de intro para terminar, sólo tendrías que identificar los caracteres del 0 al 9 para añadirlos a la cadena de texto y luego usar ATOI para convertirlo en un valor al pulsar intro.
Era algo como:
int letra, anterior_letra;
string informacion;
int salir;
salir = false;
while (!salir)
letra = ascii;
if ((letra != 0) && (letra != anterior_letra))
switch (letra)
case 9: informacion = substr(informacion, -1); end //Botón de borrar
case 13: salir = true; end //Se ha pulsado enter, pero no recuerdo si el código era 10 o 13
case 32..255: informacion = informacion + itoa(letra); end //Esto es para todas las letras, puedes usar sólo el rango de caracteres ASCII que contienen los números
end //switch
end
tecla = anterior_tecla;
frame;
end
Es sólo un esbozo, está hecho de memoria y no sé si está correcto, pero es uno de los códigos más útiles en los DIV-like, es la mejor manera que conozco de obtener un input por teclado.
Si te referías a otra cosa ¡me has hecho perder 10 minutos de mi tiempo! >:(
:D :D :D
Eso era expresamente lo ae quería, incluso lo encotré en la biblia, pero me faltaba el ATOI ese
Lo bueno es que es un numero de tres cifras por triplicado, asi que se triplica del mismo proceso
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
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 (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
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
;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 .
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).
¿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?
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.
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í.
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
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.
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
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
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.
Cierto, mi modo de meter detrás del dcb las variables es malísimo, mejor no usar.