Abril 18, 2015, 02:22:03 AM Ultima modificación: Abril 24, 2015, 12:20:23 AM por Mataca
Hola. Tengo en una room 50 niveles, controlados por un global.level .
En cada nivel tienen que encontrar 5 objetos. Quiero cambiar el modo de juego. Quiero que por ejemplo, encontraste 3 objetos en el nivel 1 y te aburriste porque no encontrás más, hacés otro nivel. Después tenés ganas de volver al nivel 1, y que ya aparezcan los 3 objetos encontrados (como si los hubieras apretado de nuevo) y sólo te queden encontrar los otros 2.
Siempre son los mismos objetos:
obj_1
obj_2
obj_3
obj_4
obj_5

Me explico?

UP!

Sería algo asi como este juego, que recuerda las diferencias que ya encontraste en un nivel aunque no lo hayas completado:




link del juego:
https://play.google.com/store/apps/details?id=com.marigames.findthedifferencen1

Lee el tutorial 08_Levels_And_Saving que está dentro de la sección 00 - GM Basics
https://imagizer.imageshack.us/v2/858x597q90/845/99v8f.jpg

Cita de: Clamud en Abril 18, 2015, 07:19:39 PM
Lee el tutorial 08_Levels_And_Saving que está dentro de la sección 00 - GM Basics
https://imagizer.imageshack.us/v2/858x597q90/845/99v8f.jpg

Ya lo leí. Se hacer eso. Lo que yo quiero es que ademas del nivel bloqueado/desbloqueado , guarde características de cada nivel.

Por ejemplo:

Nivel 1: Encontró 2/5 objetos.
Nivel 2: Encontró 4/5 objetos.
Nivel 3: Encontró 3/5 objetos.

Quiero que por nivel (lo cual lo controlo con global.nivel = 1,2,3,4,5,...50) guarde los objetos que encontró, asi por ejemplo al volver al nivel 1, los objetos obj_2 y obj_5 ya se encontraron y resten los obj_1, obj_3 y obj_4.

Sería algo así como guardar en un .ini lo siguiente:

if global.nivel = 1 obj_2 == true and obj_5 == true.

Puedes hacer eso con un arreglo 2D de tamaño 50x5, aunque escribir uno a uno los elementos del arreglo en un archivo ini me parece demasiado, optaría por usar una "grid" (también de 50x5) en vez de un arreglo para guardar toda la tabla en una sola línea del archivo ini. Pensándolo mejor se debería ser de tamaño 50x6; las primeras 5 filas serían para el estado de los objetos y la sexta para el total de objetos encontrados en cada nivel.

El procedimiento sería algo así:

Primero se crea la tabla
[gml]global.tabla = ds_grid_create( 50, 6 );[/gml]
al principio todos los valores dentro de la tabla son cero. En seguida se carga la tabla desde el ini con la función ds_grid_read. Busca la función en el manual, ahí aparece un ejemplo.

Después al entrar a un nivel (room), en el evento Room Start o Create, los objetos revisan si han sido encontrados, entonces se destruyen
[gml]///obj_1
if global.tabla[# global.level-1, 0 ] instance_destroy();[/gml]
[gml]///obj_2
if global.tabla[# global.level-1, 1 ] instance_destroy();[/gml]
se pone global.level-1 porque los niveles se empiezan a contar desde 1 pero en la tabla se cuenta desde 0.

Al encontrar un objeto se deben ejecutar algunas de estas líneas de código
[gml]//ob_1
global.tabla[# global.level-1, 0 ] = true;
global.tabla[# global.level-1, 5 ] += 1;
instance_destroy();[/gml]
[gml]//ob_2
global.tabla[# global.level-1, 1 ] = true;
global.tabla[# global.level-1, 5 ] += 1;
instance_destroy();[/gml]

Para guardar los cambios se debe usar la función ds_grid_write. En el manual también hay un ejemplo.

En la room de selección de niveles los números se escribirían con un ciclo for
[gml]
for( i=0; i<50; i++ )
{
    draw_text( x,y+i*k, "Level "+string(i+1)+": "+string(global.tabla[#i,5])+"/5" );
}
[/gml]

Hace un tiempo hice un ejemplo en que se guardaban las monedas que se hiban agarrando y cuando se volvia a jugar las que se habian agarrado no aparecian. Usa un archivo ini para guardar. Cuando se agarra la moneda esat guarda su id en el ini y se destruye, cuando se vuelve a jugador cada moenda comprueba si su id esta en el ini y si lo esta se destruye al inicio

Cita de: Clamud en Abril 19, 2015, 04:46:14 AM
Puedes hacer eso con un arreglo 2D de tamaño 50x5, aunque escribir uno a uno los elementos del arreglo en un archivo ini me parece demasiado, optaría por usar una "grid" (también de 50x5) en vez de un arreglo para guardar toda la tabla en una sola línea del archivo ini. Pensándolo mejor se debería ser de tamaño 50x6; las primeras 5 filas serían para el estado de los objetos y la sexta para el total de objetos encontrados en cada nivel.

El procedimiento sería algo así:

Primero se crea la tabla
[gml]global.tabla = ds_grid_create( 50, 6 );[/gml]
al principio todos los valores dentro de la tabla son cero. En seguida se carga la tabla desde el ini con la función ds_grid_read. Busca la función en el manual, ahí aparece un ejemplo.

Después al entrar a un nivel (room), en el evento Room Start o Create, los objetos revisan si han sido encontrados, entonces se destruyen
[gml]///obj_1
if global.tabla[# global.level-1, 0 ] instance_destroy();[/gml]
[gml]///obj_2
if global.tabla[# global.level-1, 1 ] instance_destroy();[/gml]
se pone global.level-1 porque los niveles se empiezan a contar desde 1 pero en la tabla se cuenta desde 0.

Al encontrar un objeto se deben ejecutar algunas de estas líneas de código
[gml]//ob_1
global.tabla[# global.level-1, 0 ] = true;
global.tabla[# global.level-1, 5 ] += 1;
instance_destroy();[/gml]
[gml]//ob_2
global.tabla[# global.level-1, 1 ] = true;
global.tabla[# global.level-1, 5 ] += 1;
instance_destroy();[/gml]

Para guardar los cambios se debe usar la función ds_grid_write. En el manual también hay un ejemplo.

En la room de selección de niveles los números se escribirían con un ciclo for
[gml]
for( i=0; i<50; i++ )
{
    draw_text( x,y+i*k, "Level "+string(i+1)+": "+string(global.tabla[#i,5])+"/5" );
}
[/gml]

Excelente! Lo del grid me anduvo espectacular.
Ahora los problemas que tengo son para guardar/cargar (lei el manual y lo intente de varias formas, pero no me sale) y tambien lo del draw_text en los niveles, pongo ese código y me salta error en cualquier evento, ya sea draw, create, step....

¿Qué error te aparece?
Recuerda que antes de cargar la grid desde el ini ya debe haber una grid valida escrita en éste.

Cita de: Clamud en Abril 20, 2015, 03:56:12 PM
¿Qué error te aparece?
Recuerda que antes de cargar la grid desde el ini ya debe haber una grid valida escrita en éste.
Me aparecen varios errores... es según cómo lo haya intentado...
No se como tendría que poner el grid en el ini... ni como tendria que poner el código para guardar/cargar... ese es el problema. En el manual te muestra ejemplos de cargar y de guardar por separado, no un ejemplo "entero". En este caso tendría que cargar/guardar una grid de 50*6.
Sabrías como hacerlo?

¿Has usando archivos ini anteriormente? Si no lo has hecho, es mejor que practiques un poco con algo más sencillo (como escribir y leer un simple número), hay muchos ejemplos en el foro.

Puedes poner esto al inicio del juego para cargar los datos. Si ves otros ejemplo te darás cuenta que son muy parecidos.
[gml]
global.grid = ds_grid_create( 50, 6 ); //crear la grid

ini_open( "save.ini" ); //abrir archivo ini, si no existe se crea

if ini_key_exists( "Datos", "objetos" ) //si la línea que buscamos existe
ds_grid_read( global.grid, ini_read_string( "Datos", "objetos", "0" ) ); //cargar grid
else //si no se ha guardado la grid
ini_write_string( "Datos", "objetos", ds_grid_write( global.grid ) ); //la guardamos de una vez (por ahora está en ceros)

ini_close(); //cerrar ini y guardar los cambios
[/gml]

Si has escrito muchas cosas en el archivo y no estás seguro de que los datos son correctos, borra el archivo para comenzar de nuevo con uno en blanco
[gml] file_delete( "save.ini" )[/gml]
eso lo puedes poner dentro de un evento press del teclado o poner una opción dentro de un menú de tu juego (algo como "Borrar datos").

El código para guardar la grid lo debes poner en donde quieras; puedes ejecutarlo al encontrar un objeto para que el archivo ini siempre esté actualizado, otra opción es ejecutarlo en un evento room end y otra es ponerlo en un evento game end
[gml]
ini_open( "save.ini" );
ini_write_string( "Datos", "objetos", ds_grid_write( global.grid ) );
ini_close();
[/gml]

Cita de: Clamud en Abril 20, 2015, 05:19:39 PM
¿Has usando archivos ini anteriormente? Si no lo has hecho, es mejor que practiques un poco con algo más sencillo (como escribir y leer un simple número), hay muchos ejemplos en el foro.

Puedes poner esto al inicio del juego para cargar los datos. Si ves otros ejemplo te darás cuenta que son muy parecidos.
[gml]
global.grid = ds_grid_create( 50, 6 ); //crear la grid

ini_open( "save.ini" ); //abrir archivo ini, si no existe se crea

if ini_key_exists( "Datos", "objetos" ) //si la línea que buscamos existe
ds_grid_read( global.grid, ini_read_string( "Datos", "objetos", "0" ) ); //cargar grid
else //si no se ha guardado la grid
ini_write_string( "Datos", "objetos", ds_grid_write( global.grid ) ); //la guardamos de una vez (por ahora está en ceros)

ini_close(); //cerrar ini y guardar los cambios
[/gml]

Si has escrito muchas cosas en el archivo y no estás seguro de que los datos son correctos, borra el archivo para comenzar de nuevo con uno en blanco
[gml] file_delete( "save.ini" )[/gml]
eso lo puedes poner dentro de un evento press del teclado o poner una opción dentro de un menú de tu juego (algo como "Borrar datos").

El código para guardar la grid lo debes poner en donde quieras; puedes ejecutarlo al encontrar un objeto para que el archivo ini siempre esté actualizado, otra opción es ejecutarlo en un evento room end y otra es ponerlo en un evento game end
[gml]
ini_open( "save.ini" );
ini_write_string( "Datos", "objetos", ds_grid_write( global.grid ) );
ini_close();
[/gml]

Excelente! Uso archivos .ini para guardar varias cosas... ahora le sume el global.grid del manual que me hiciste. Me anduvo perfecto, muchisimas gracias!

Ahora solo me resta poder ponerlo en la pantalla de seleccion de niveles.
Probé con el código que me dejaste pero me salta error:
Cita de: Clamud en Abril 19, 2015, 04:46:14 AM
En la room de selección de niveles los números se escribirían con un ciclo for
[gml]
for( i=0; i<50; i++ )
{
    draw_text( x,y+i*k, "Level "+string(i+1)+": "+string(global.tabla[#i,5])+"/5" );
}
[/gml]

Lo traté de poner en un objeto de nivel, y despues en otro independiente y me salta error.

Yo tengo la pantalla de selección de niveles asi:


Obviamente son más niveles, son 50, los tengo con una view y lo bajas con el mouse.

Lo que quiero es en cada boton (porque cada nivel es un boton que va al room con ese nivel) tenga por ejemplo a la derecha abajo los objetos descubiertos/restantes ( 1/5, 2/5, 3/5, 4/5 o 5/5).
Cual sería el código para un nivel? Asi lo hago con todos.

Deberias poner el error que aparece para que sea más fácil ayudarte. Me imagino que el último error se debe a que no has asignado la variable "k", lo dejé así para que el valor lo asignes tú.
Para hacer botones usa un script como éste http://www.comunidadgm.org/desarrollo-de-scripts/botones-automaticos/

Cita de: Clamud en Abril 21, 2015, 04:13:00 AM
Deberias poner el error que aparece para que sea más fácil ayudarte. Me imagino que el último error se debe a que no has asignado la variable "k", lo dejé así para que el valor lo asignes tú.
Para hacer botones usa un script como éste http://www.comunidadgm.org/desarrollo-de-scripts/botones-automaticos/
Si, el error era ese. El problema ahora es que lo puse asi:

for( i=0; i<50; i++ )
{
    draw_text( 100,300, "Level "+string(i+1)+": "+string(global.grid[#i,5])+"/5" );
}


Y me queda todo superpuesto:


No entiendo bien como es... como tomaría cada draw para cada nivel diferente... Yo lo que quiero es que por cada nivel en la seleccion de niveles te diga los que encontraste/restantes. Algo asi sería la maqueta:


Debería de ser un draw para cada objeto, no?. Tengo 50 objetos en el room ese, con una view para scrollear.

up!.

Alguien sabría como sería el código para un solo level? Hago 50 draws por separado igual... Es lo unico que me falta para terminar ! :)

El problema con el draw es que no varias la x ni la y. Dibujas 50 veces los mismo encima. Tienes que poner una x o y diferente por cada for. Aqui ua depende de la distribucion de tu pantalla.
Yo en un caso parecido tengo esto es un for
draw_tex (x+xx*128, y+yy*128, string)
If xx = 5 {xx=0; yy=1}
Eso dentro del for. Asi me pone 4 textos lor línea,  con una separacion de 128 pixeles. Tu ya ajustalo a tu pantalla.