Buenas, pues tengo una cuestion y no se muy bien como plantearla, los que habeis hecho algun tipo de inventario creo que podreis ayudarme.

El caso es el siguiente. El player va recogiendo discos de ordenador, cada disco tendra un numero distinto e ira recogiendo y sumando discos. Cada disco contiene una informacion distinta.

A la hora de chequear los discos, como compruebo los discos que tengo y a la vez visualizarlo.

Como he dicho antes, creo que esto seria lo mas semejante a abrir un inventario, creo yo.

Bueno espero vuestros consejos. Saludos y gracias.  ;)
PCNONOGames  www.pcnono.es

Una forma es usando arrays. Empiezas el juego con cero discos, ponemos un objeto para controlar esos datos:

EVENTO CREATE

global.discos=0  // Número de discos en nuestro inventario
for(i=1;i<=50;i+=1) // Loop entre todos los discos, la cifra es sólo orientativa
{
global.disco[i]=0  //  Esta variable nos dirá si tenemos o no un disco en particular en nuestro inventario
}


Y desde ya dibujamos la variable de nuestro total de discos (dentro del objeto controlador, no del disco en si mismo):

EVENTO DRAW
draw_text(x,y,string(global.discos))

Y ahora ya sí pasamos al objeto_disco; añadimos el código que nos dirá qué número de disco es:

EVENTO CREATE
disco=instance_number(objeto_disco)

Cuando el personaje coge el disco, por ejemplo al clicarlo, si no lo tenía ya, añade ese número de disco a su inventario:

EVENTO LEFT PRESSED

if global.disco[disco]=0{global.discos+=1;global.disco[disco]=1}else show_message("Este disco ya lo tengo!");exit}


Muchas gracias por responder Arcadian, pero justo antes ya lo habia programado. El caso es que al coger el disco 46 no me da ningun error, pero al coger el disco 45 me sale este error. y no entiendo porque.

FATAL ERROR in
action number 1
of Create Event
for object objectMENU_DISCOS:

Push :: Execution Error - Variable Index [0,65] out of range [1,65] - -5.DISCO(100040,65)
at gml_Object_objectMENU_DISCOS_CreateEvent_1 (line 34) -     if (DISCO==true)


Este es el codigo que uso.

CREATE;
//VARIABLES DE LOS DISCOS
globalvar DISCO;
globalvar BOLSILLO_MAXIMO;
BOLSILLO_MAXIMO = 65;
globalvar CODIGO;

for(i=45;i<BOLSILLO_MAXIMO;i++)
{
    DISCO=false;
    CODIGO=0;
}

AL COGER EL DISCO EN COLISION EVENT

if !audio_is_playing(soundDISKETERA_PASANDO)
if (bandera_sonar)
{
    audio_play_sound(soundDISKETERA_PASANDO,1,0);
    bandera_sonar = false;
}

DISCO[numero]= true;

*numero es el numero del disco.

AL CARGAR EL ESPECIE DE INVENTARIO

BOLSILLO_MAXIMO = 65;

for(i=45;i<BOLSILLO_MAXIMO;i++)
{
    if (DISCO==false)
    {
        i++;
    }
   
    if (DISCO==true)
    {
        DISCO_CARGADO = i;
        CODIGO_CARGADO = CODIGO;
    }
}

}

lo guardo todo en dos nuevas variables para usarlo con mas facilidad. El for comienza a partir de 45, solo por motivos de gusto, para no usar disco 1 disco 2, para que suena mas real.
El caso que primero lo probe con el disco 46 y me funciono, pero al poner el disco 45, me sale el error de fuera rango. No entiendo.

Bueno si alguien ve algo que me comente please.




Cita de: Arcadian en Mayo 27, 2017, 03:08:41 PM
Una forma es usando arrays. Empiezas el juego con cero discos, ponemos un objeto para controlar esos datos:

EVENTO CREATE

global.discos=0  // Número de discos en nuestro inventario
for(i=1;i<=50;i+=1) // Loop entre todos los discos, la cifra es sólo orientativa
{
global.disco[i]=0  //  Esta variable nos dirá si tenemos o no un disco en particular en nuestro inventario
}


Y desde ya dibujamos la variable de nuestro total de discos (dentro del objeto controlador, no del disco en si mismo):

EVENTO DRAW
draw_text(x,y,string(global.discos))

Y ahora ya sí pasamos al objeto_disco; añadimos el código que nos dirá qué número de disco es:

EVENTO CREATE
disco=instance_number(objeto_disco)

Cuando el personaje coge el disco, por ejemplo al clicarlo, si no lo tenía ya, añade ese número de disco a su inventario:

EVENTO LEFT PRESSED

if global.disco[disco]=0{global.discos+=1;global.disco[disco]=1}else show_message("Este disco ya lo tengo!");exit}

PCNONOGames  www.pcnono.es

La variable DISCO comienza con valor de cero, y en tu array el valor mínimo para i es 45.

De todas formas revisa tu ciclo for, estas usando esa variable por un lado pero luego tienes otra llamada DISCO[] que es un array pero que no usas dentro del loop, no esta muy católico ese código...


DISCO lo tengo igual que false. Que supongo que es a lo que te refieres a que lo inicio a 0.

Y si, uso la variable de array sin loop. Eso esta mal??

Y porque con el DISCO 46 funciona perfecto???

Voy a tener que revisarlo pero aun no entiendo que pasa.

Muchas gracias. ;)



Cita de: Arcadian en Mayo 28, 2017, 08:58:04 PM
La variable DISCO comienza con valor de cero, y en tu array el valor mínimo para i es 45.

De todas formas revisa tu ciclo for, estas usando esa variable por un lado pero luego tienes otra llamada DISCO[] que es un array pero que no usas dentro del loop, no esta muy católico ese código...
PCNONOGames  www.pcnono.es

¿Y si usas mapas? Tal vez te sea más sencillo
[gml]
///Evento create del objeto inventario
global.discos = ds_map_create();

///Evento create del objeto disco
disco_id = instance_number(obj_disco);

///Evento de colisión del disco con el jugador (o lo que sea xd)
if (bandera_sonar)
{
    audio_play_sound(soundDISKETERA_PASANDO, 1, 0);
    bandera_sonar = false;
}

global.discos[? disco_id] = mi_codigo; //la variable 'mi_codigo' es la información del disco
[/gml]
Y cuando quieras mostrar en pantalla cada código de disco con su respectiva información, harías algo así:
[gml]
///Evento draw del inventario
num = ds_map_size(global.discos);
ide = ds_map_find_first(global.disco);
for(var i = 0; i < num; i++)
{
    draw_text(32, 32 + 32*i, string(ide) + ": " + string(global.discos[? ide]));
    ide = ds_map_find_next(global.discos, ide);
}
[/gml]
Se mostrarían en plan:
Citar
Disco N: Dato N
Disco X: Dato X
Disco Y: Dato Y
alaberga regué el café.

BA:STFW&RTFM

A mi me falta código, nonoroman, hay algo que no hayas puesto?

Por ejemplo esto, donde declaras el valor de la variable "numero", no lo veo por ninguna parte:


DISCO[numero]= true;

*numero es el numero del disco.

#7 Mayo 29, 2017, 04:46:36 PM Ultima modificación: Mayo 29, 2017, 04:53:45 PM por nonoroman
Lo primero, muchas gracias por todos vuestros consejos.

El ejemplo de Niuweb, nunca lo he utilizado, y la verdad, no llego a entenderlo completamente.

El codigo que os pase, realmente funciona, cuando cojo el disco 46, pero al coger otro disco, por ejemplo el 45 o 47 da el error de variable index out range.

Pero en teoria esta todo bien.

Os explico mi codigo para estrofa a estrofa, para que entre todos intentemos dar con el problema.

Antes de comenzar el juego declaro unas variables globales en el Create de un objecto. En ella se estable el for de los discos y codigos que contienen los discos.

//VARIABLES DE LOS DISCOS
globalvar DISCO;
globalvar BOLSILLO_MAXIMO;
BOLSILLO_MAXIMO = 65;
globalvar CODIGO;

for(i=45;i<BOLSILLO_MAXIMO;i++)
{
    DISCO[i]=false;
    CODIGO[i]=0;
}

Utilizo los numero del 45 al 65, e inicializo todos los DISCO[45] hasta el DISCO[65] a false.
y los CODIGOS del 45 al 65 lo inicio a 0.

En el CREATE de cada DISCO inicio estas variables.

numero = 45;
CODIGO[numero]=2580;


en numero, declaro el numero del disco, y en CODIGO introduzco la informacion o clave que va llevar dicho disco.

Al COLISIONAR el jugador con el disco. simplemente pongo dicho disco en true. aqui esta.

DISCO[numero]= true;

Es decir, DISCO[45] ahora es true, es decir, que ahora el player lleva el disco con el.

Ahora, al darle al INVENTARIO (que no es un inventario exactamente, pero se puede entender como tal)

Revisamos otra vez el array con el FOR. En el inventario, solo puede visualizar a la vez, solo UN DISCO, para pasar de un disco a otro utilizare unas flechas, pero repito, solo puedo visualizar en grande UN SOLO DISCO. Por lo tanto el FOR quedaria asi.

CREATE DEL INVENTARIO

BOLSILLO_MAXIMO = 65;

for(i=45;i<BOLSILLO_MAXIMO;i++)
{
    if (DISCO[i]==false)
    {
        i++;
    }
   
    if (DISCO[i]==true)
    {
        DISCO_CARGADO = i;
        CODIGO_CARGADO = CODIGO[i];
    }
}

}


Comenzando desde i=45 hasta el 65 comprobamos si la variable DISCO esta a true (es decir, que el player lo ha cogido). Si es false, pasamos al otro DISCO, asi hasta llegar al primero que este en true. Ejemplo, DISCO[45] esta a true (que es con el que me falla)

Al estar en true, entra en la condicion, y como solo podemos visualizar en grande un solo disco, pues al ser este el primero, este va ser el primero en visualizarse, para ello, utilizamos las variables globales DISCO_CARGADO donde cogemos el valor de i, que es el numero correspondiente del disco y CODIGO_CARGADO, donde cogemos el valor de CODIGO, que fue donde al coger el disco el jugador, guardamos la informacion del disco, de esta manera, CODIGO[45].

Despues en el DRAW del inventario dibujamos el DISCO y en el escribimos lo siguiente, una etiqueta que va dibujada en el disco con su numero correspondiente con la variable DISCO_CARGADO.

if (TENEMOS_DISCOS)
{

    draw_text(x+sprite_width/2,y+sprite_height/2+50,string("ACESSO#"
    + string(DISCO_CARGADO)));
}


Luego, el siguiente paso es mostrar la informacion del disco con la variable CODIGO_CARGADO, pero eso ya seria el siguiente paso, hasta aqui ya se produce el error;

FATAL ERROR in
action number 1
of Create Event
for object objectMENU_DISCOS:

Push :: Execution Error - Variable Index [0,65] out of range [1,65] - -5.DISCO(100040,65)
at gml_Object_objectMENU_DISCOS_CreateEvent_1 (line 34) -     if (DISCO[i]==true)




EN TEORIA YO LO VEO TODO BIEN!!!! Si alguien ve algo mal que me lo indique, porque el caso es que al coger el DISCO 46, si que funciona, y el disco 45 es una duplicacion de este, solo que le cambio el valor de la variable numero a 45, que es el que indica que es el disco 45. Asi que no entiendo nada.

Bueno si alguien ve algo que me comente. He intentado explicarlo al maximo posible ya que algunos me pedian que faltaban cosas. Creo que con esto esta todo.

Bueno a ver si juntos lo resolvemos. Gracias a todos. 

???
PCNONOGames  www.pcnono.es

El error -probablemente- está aquí:
[gml]
for(i=45;i<BOLSILLO_MAXIMO;i++)
{
    if (DISCO==false) //Desde aquí
    {
        i++;
    } //Hasta aquí :v
   
    if (DISCO==true)
    {
        DISCO_CARGADO = i;
        CODIGO_CARGADO = CODIGO;
    }
}
[/gml]
Si la primera condición se ejecuta, se sumará 1 a i y se avanzará el ciclo. El problema viene después, cuando la siguiente iteración se inicia, la misma operación del ciclo vuelve a sumar 1 a i, y eso hace que se salga del límite del arreglo. Puedes intentar modificarlo así:
[gml]
for(i=45;i<BOLSILLO_MAXIMO;i++)
{

    if (DISCO)
    {
        DISCO_CARGADO = i;
        CODIGO_CARGADO = CODIGO;
    }
}
[/gml]
Sencillito, sólo eliminas la primera condición.
alaberga regué el café.

BA:STFW&RTFM

Hostias NiuWeb. Efectivamente ahora funciona. Que maquina eres tio.

Entonces lo que pasaba, es que se metia en un bucle do de i no paraba de sumarse hasta que este se salia del rango del mientras del for.

Eso es lo que pasaba. Noo??

De todas formas muchas gracias a todos y sobre todo a NiuWeb. Que ha sido el que ha dado en el clavo.
Fijate que cosa mas tonta era. Muchas gracias de verdad.  ;D ;D ;D

[q ;Duote author=NiuWeb link=topic=28954.msg127308#msg127308 date=1496079357]
El error -probablemente- está aquí:
[gml]
for(i=45;i<BOLSILLO_MAXIMO;i++)
{
    if (DISCO==false) //Desde aquí
    {
        i++;
    } //Hasta aquí :v
   
    if (DISCO==true)
    {
        DISCO_CARGADO = i;
        CODIGO_CARGADO = CODIGO;
    }
}
[/gml]
Si la primera condición se ejecuta, se sumará 1 a i y se avanzará el ciclo. El problema viene después, cuando la siguiente iteración se inicia, la misma operación del ciclo vuelve a sumar 1 a i, y eso hace que se salga del límite del arreglo. Puedes intentar modificarlo así:
[gml]
for(i=45;i<BOLSILLO_MAXIMO;i++)
{

    if (DISCO)
    {
        DISCO_CARGADO = i;
        CODIGO_CARGADO = CODIGO;
    }
}
[/gml]
Sencillito, sólo eliminas la primera condición.
[/quote]
PCNONOGames  www.pcnono.es