Busco inventario

Started by Abash, March 08, 2013, 06:45:42 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Abash

Por casualidad alguien tiene algún ejemplo básico de inventario?
Unas casillas donde se depositen objetos y se puedan mover con el ratón de una casilla a otra o soltarlos fuera de las casillas.
Que se puedan acumular objetos...
E estado mirando algún que otro ejemplo, pero claro, entre enemigos, menús, tablas y demás cosas no veo claramente como es la cosa.
Digamos que lo que es la parte gráfica ya la tengo. Desplegar un menú con casillas vacías y un personaje que toque objetos y estos desaparezcan pero me falta la parte de meterlos en el inventario y demás.
Si no tenéis ejemplo, con explicarme como va el tema supongo que me apaño. Quiero decir, los pasos que se siguen.

DCelso

creaz una vector bidimensional, matriz, con el número de cuadrados (huecos) que tiene, y en ella guardas un 0 si está libre y un 1 u otro valor si está ocupado, y al soltar un objeto tienes que ver qué posiciones de la matriz ocupa tu imagen para ocuparlos.
Es técnica tetris, columns, dr-mario, etc. puedes ver la técnica  en mi código apagame en cualquiera de los que te mencioné. El proyecto nació para eso para servir de mini tutos de mini técnicas de mini juegos, pero se quedó estancado, por falta de tiempo. ánimo y colaboraciones entre otras cosas.  :D.

Monstruos Diabólicos

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

Erkosone

Crear un inventario "en condiciones" es bastante simple, pero debes diseñarlo todo antes de ponerte a programarlo, bueno, esto es algo que he hecho muchas veces en muchos lenguajes y te puedo asesorar un poco jeje.. vamos a ver..


A la hora de crear un inventario puedes enfocar el tema desde varios puntos de vista, pero en definitiva existen 2 formas de hacerlo, la que no me gusta.. que es la desordenada con todos los datos revueltos y por separado, y la segunda forma, donde lo que hace el inventario en si no es mas que las veces de un simple visor de objetos, es por esto que tienes que tener en cuenta algo mas que la idea del inventario a secas, y es la de crear un prototipo de dato bien definido para alojar en el inventario, que al final el inventario será unicamente una ventanita de visualización de una lista de objetos.


Lo complejo es sin duda crear la ventanita de visualización y que funcione bien y sea agradable en uso al usuario.
Lo sencillo, es crear el prototipo de objeto "Item" mediante un sencillo typedef que servirá de base para todo lo que quieras alojar en el inventario.


Empezamos por lo sencillo.
Prototipo de dato ITEM:
- Por su propia definición ha de ser algo similar a una estructura de datos, así que vamos a pensar en que propiedades debería tener para ser alojable en un inventario.


Propiedades del objeto ITEM:
- Nombre_.
- Descripción_.
- fpg_icon.
- numMap_icon.
- Cantidad_.
- _Available_.
- _drag_.
- data_0_;
- data_1_;
- data_2_;


- Seguramente mientras vamos hablando del tema vayamos viendo que hacen falta algunos campos mas, pero en principio esto es lo estrictamente necesario para empezar a plantear un item de inventario, las propiedades responden a lo siguiente:
*NOMBRE: Nombre del item que será mostrado por el inventario.
*DESCRIPCION: Breve texto que describe al item, el inventario podrá mostrarlo.
*FPG_ICON: Fichero FPG donde está alojado el icono del item.
*NUMMAP_ICON: Posición dentro de FPG_ICON que se corresponde al icono del item.
*CANTIDAD: Número de items de identicas caracteristicas que se encuentran amontonados en una unica casilla del inventario, osea, si tienes 2 panes no hará falta que estén ocupando 2 casillas del inventario, estarán en 1 y se mostrará el número '2' encima del icono del item.
*AVAILABLE: Variable que estará en FALSE cuando el item no sea utilizable aunque se posea, estará en TRUE cuando el item pueda ser usado.
*DRAG: Valdrá FALSE y solo estará en TRUE cuando el item esté siendo arrastrado con el mouse para eliminarlo arrastrandolo fuera del inventario o para colocarlo en otra casilla del inventario.
* DATA[]´S: Son variables de reserva para proveer de posibles necesidades al inventario en el futuro, se deben crear algunas variables reserva por si surge el momento en el que el inventario se ha guardado en disco en un archivo y se desean ampliar las propiedades de los item´s, "cosa bastante habitual", si para esto de necesitar ampliar el prototipo de dato ITEM podríamos encontrarlos en la encrucijada de que el archivo a cargar ya no es compatible con la estructura actual de datos del programa y no carge bien corrompiendo los datos o simplemente dando error al faltar o sobrar datos.




Vale teniendo esto en cuenta ya se puede diseñar un inventario mas o menos interesante.. te gusta este planteamiento? o andabas buscando algo mas básico?
Lo digo por no enrrollarme demasiado XD..

Abash

Si, es ese el tipo de inventario en el que estaba pensando. De echo por eso digo que me pierdo. Estaba buscando algún ejemplo y de lo poco que encontré fue el DEEP DUNGEON de los ejemplos de Bennu y que casualmente veo que usa algo similar a lo que me dices. Por eso decía lo de algún ejemplo, en plan solo esa parte. Aunque solo fuera un ejemplo sin fondo ni nada con 2 objetos, uno apilable hasta una cierta cantidad y otro que ocupe solo 1.
Te cuento de que va el tema y así me entiendes. Empece con un simple editor de tiles. Como me hacían falta gráficos, me baje un pack.
Puñetero pack que traía todos los gráficos de los tiles del Terraria. Fui cambiando tanto el editor, que e llegado a hacerlo en plan autotile con sus 16 partes de tiles diferentes x3 cada tile si lo pongo en random. Osea, elijo un material y creo el mapa como si dibujara en cualquier programa de dibujo. Van cambiando los tiles según los tiles que tengan al lado.
En principio solo quería eso, pero me dije, y si le puedo meter un personajillo? Dicho y hecho.
Y me e quedado no en esa parte, en la siguiente. Tengo un proceso que sale cada vez que borro un tile osea, click derecho. Este proceso lo único que tiene en su código es la gravedad y cae hasta que colisiona con alguna parte del mapa. El prota al tocarlo lo mata desapareciendo el tile. La parte gráfica del inventario la tengo. En realidad los huecos son como botones semitransparentes cada uno independiente. Esa parte la e echo así porque creo que es mas fácil acceder a cada uno por separado ya que incluso puedo mostrar cualquier digamos objeto en cada hueco.
Y aquí estoy, no se como unir digamos el "tocamiento" del personaje jejeje con los objetos que encuentra, y un inventario.
Cualquier día de estos lo posteo por aquí, eso si, no se si podre volver después porque ya se que me pondréis a caldo jajajaja pero bueno, puede que a alguien le haga falta para algo o seguirlo.

Erkosone

entiendo.. al final te ha pasado como a todos, empiezas con algo sencillo y cuando quieres darte cuenta llevas 5 años metiendole cosas y al final ya no sabes ni lo que es XD..


Voy a intentar hacer un ejemplo y te lo paso, haber que tal queda y si te gusta usalo sin problema en tu juego ;)

Erkosone

Objetivo completado!


- Ya tengo el inventario con todo lo que necesitabas, las features son estas:
- Objetos sueltos por pantalla que pueden añadirse a un inventario con drag&drop.
- Objetos apilables en los slots del inventario.


Particularidades:
- Si se intenta arrastrar un objeto a un slot del inventario que esté ocupado pasa lo siguiente:
A: Si el objeto/s que ya están en el slot del inventario son del mismo tipo que el objeto que se pretende soltar en ese mismo slot se aplilaran.
B: Si son de tipos distintos al soltar el objeto en el slot del inventario el objeto se devolverá al lugar donde se recogió con el mouse.






Bueno muchacho espero que te sirva, el nivel del código creo que es un poco mas elevado que "basico" como tu pedias pero oye.. esto de los inventarios no es algo simple XD..
Espero que te sirva y que entiendas el código, he intentado dejarlo todo lo mas modularizado posible para ampliarlo sin problemas pero tiene algunas cosillas que hay que tener en cuenta:


En muchas partes del código veras los siguientes valores en operaciones simples de mates:


125 = es la mitad del ancho|alto del gráfico de la cuadricula del inventario.
25 = es la mitad del ancho|alto de una celda de la matriz.
/ 5 = 5 son las celdas tanto a lo ancho como a lo alto de la matriz de slots del inventario.


Se podía haber hecho completamente automatico pero vaya.. que como es un ejemplo tampoco me he matado a pulir demasiado.
Un saludo y espero que sea mas o menos lo que necesitabas ;)


Abash

Eso era lo que necesitaba, me va perfecto. Ahora me toca adaptarlo a lo que necesito. Algo así tenia medio echo pero me faltaba como quien dice, el lazo de unión. Me ayuda muchísimo el tener solo esa parte sin nada mas como pudieran ser enemigos, pantallas de inicio, movimientos, animaciones... que al final, cuando uno sabe poco como en mi caso, lo único que hace es liar mas la cosa.
  Si te pasas por el norte te invito a un café jajaja.
Seguramente a alguien le vendrá también muy bien. Gracias  :)

Erkosone

Me alegro de que te sirva, ahora solo tienes que añadirle algunos detalles y ya lo tienes, lo que quizá le falta es la funcionalidad de destruir items que ya están en el inventario arrastrandolos fuera de el, o apilar 2 montones que ya están en el inventario, pero es bastante sencillo de hacer, por si te hiciera falta te explico la idea:


Ahora tenemos en este ejemplo que agarras un item que está en la escena y puedes alojarlo en el inventario, justo cuando agarramos al item que está en la escena guardamos su posición por si el resultado de incrustarlo en el inventario fuera negativo poder devolverlo a donde estaba, vale.. pues en la acción contraria hay que hacer algo similar.


Osea, la cosa sería así:


1 - Colisiona el proceso ID_MOUSE con la textura de la matriz del inventario?
2 - Recuperamos el número de SLOT con el que colisiona el mouse con la función inventory_get_slot_by_xy();
3 - Está en 'bussy' este SLOT?
4 - Se hace click con el mouse?
5 - ** Crear un proceso con la información del contenido del SLOT y dejarlo siguiendo al mouse.
6 - ** Liberar el SLOT del inventario con la función inventory_clear_item();


Y ya estaría todo, ahora tendrías un objeto agarrado por el mouse con las caracteristicas de lo que contenía el SLOT y el SLOT está vacío, puedes soltar el contenido en otra casilla del inventario o soltarlo fuera de el y depende lo que hagas así actuas, los apilas de nuevo, eliminas el objeto y bla bla..


Como ves es mas sencillo de lo que parece, solo hay que organizar bien la base para que luego todo encaje ;)

Abash

Me han venido muy bien esas explicaciones. Cambiando unas cosillas y metiendo otras lo e podido adaptar a lo necesitaba. Aunque me falta una cosa mas por implementar en los Case, que es que hacer cuando todos los huecos están completos. Lógicamente, dejarlo donde estaba jejeje pues aquí me e quedado atascado. En esta tontería. Como se hace esa comprobación? no hace falta código, con dar una breve explicación de como se hace supongo que me sirve.
Tal como lo tengo ahora, los objetos se auto apilan por tipo y hasta un máximo por hueco. Cuando llegan al máximo por hueco empiezan a ocupar otro hueco y me falta eso, comprobar que todos los huecos estén completos y no apilar mas, dejarlos donde están.

Por cierto, por si alguien se lo pregunta, si, no se mucho sobre el lenguaje, pero me encanta la manera de aprenderlo y no me importa tardar tiempo en hacer cosillas.
De hecho e tardado creo que 4 días en algo tan sencillo como meter parte del código de ese inventario a lo que tengo y agregarle cosas jajaja pero no me importa, no hay prisa.
Prefiero parecer ignorante una vez a serlo toda la vida es algo así como se dice no? jejeje

Erkosone

Piensalo de esta forma:


1 - existe un slot con items del tipo que se quiere meter al inventario?
SI -> se añade a la pila o se pasa al siguiente paso si está llena..
NO -> se pasa al siguiente paso..


Paso 2:
- Hay huecos disponibles para añadir objetos?
a - comprobarlo simplemente recorriendo con un bucle FOR las casillas del inventario y mirar si la variable bussy está en true o false..


NO hay huecos: Se deja donde estaba el item..
SI hay huecos: se añade.

Abash

Muchísimas gracias Erkosone, ya lo e implementado :) no esta del todo perfecto pero me sirve. Me queda el restar cuando los gasto, pero eso es muy fácil y ya se que me funciona porque lo e probado y va bien. Quería preguntar una cosa mas y por no abrir otro post lo pregunto aquí.
Como hacéis para que al apretar un botón del raton, os cuente solo 1 aunque el botón siga apretado?
Me refiero a algo parecido a   si ratón derecho, loquesea+=1
Al apretar un botón del ratón, si lo mantengo apretado, sigue sumándose y a mi me interesa que me cuente como 1.
Es para que solo me ponga o me quite objetos, pero de 1 en 1, no de corrido.
  Dejo una muestra de lo que tengo, aunque ahora lo tengo algo mas avanzado.
Peta si te suicidas y te dejas caer, si tocas el techo superior, no borra algún texto, no esta implantado el reposicionar tiles al borrarlos... y un millón de cosas jejeje solo es una versión para probar en plan sucio y cargar rapido que uso para pruebas.

Erkosone

Gracias, me alegro de que te haya servido, sobre lo que preguntas, hay una técnica mas vieja que la propia programación jeje.. a esto que te voy a explicar se lo conoce como "máquina de estados" y es sumamente sencillo de implementar, mira te explico:




Lo primero que tienes que tener claro en algo como esto es que lo que en realidad buscas es el mecanismo de un botón, no es mas que eso.. en realidad lo que quieres es que las casillas se comporten como botones, vale.. teniendo esto claro mira como se hace:


Es imprescindible el uso de SWITCH(variable) y sus case, y te explico por que.


- Antes de comenzar el SWITCH() tienes que saber de antemano si el mouse está en una posición válida, osea, si está colisionando con una zona que realmente se comportará como un botón, esto normalmente yo lo hago así:  ID_ = collision(type mouse);  ahora mediante la variable privada 'ID_' puedo saber si el mouse está colisionando con el inventario..


ESTADO 0 - Lo primero que hay que hacer es comprobar si se está pulsando 'mouse.left', si se está pulsado se pasa al estado 1..


ESTADO 1 - Está el mouse en una posición válida? si es cierto se pasa al estado 2..


ESTADO 2 - Ahora se espera a que se deje de pulsar 'mouse.left', cuando esto ocurra se pasa al estado 3..


ESTADO 3 - Aquí se realiza la acción pertinente y se pasa al estado 0.. y como en este estado ya no se está pulsando el mouse el estado cero funcionará correctamente y se volverá a poder detectar un evento de este tipo ;)




Esto traducido a código bennu es algo así:



process test();
private
   int id_;
   int estado = 0;
begin
   graph = bla bla bla..
   LOOP
      id_ = collision(type mouse);
      switch(estado)
         case 0:
            if(mouse.left)         // se está pulsando el mouse??
               if(id_)         // está el mouse encima de mi gráfico??
                  estado = 1;   // paso al siguiente estado de la maquina de estados..
               end
            end
         end
         case 1:
            if(!mouse.left)      // se ha dejado de pulsar el mouse??
               estado = 2;      // paso al siguiente estado de la maquina de estados..
            end
         end
         case 2:
            // aquí realizar las acciones necesarias..
            // y volvemos al estado inicial..
            estado = 0;
         end
      end
      FRAME;
   END
end