2012-04-01 18 views
7

Estoy construyendo un juego de mazmorras RPG en Java y estoy atascado en la creación de una estructura de datos.¿Qué es una buena estructura de datos de Java para almacenar elementos de juegos de rol?

Tengo un montón de objetos Thing con los que puedo copiar para poblar una mazmorra. Por ejemplo, hay un objeto Thing de pan, y un objeto Thing de espada, un objeto Thing de correo de cadena, y Thing (s) de monstruo, etc. Quiero almacenarlos en una Biblioteca central y luego poder recuperar un objeto usando cierta consultas. Quiero almacenarlos usando los siguientes campos:

int minLevel 
int maxLevel 
double probability 
int[] types 

Así que una espada oxidada tendría un minLevel de 1, un maxLevel de 3, un probability de rareza (3%), y [type.SWORD,type.WEAPON,type.ITEM,TYPE.EQUIP]. Una espada mejor tendría minLevel 2, maxLevel 10, rareza (1%).

Luego quiero recuperar un type.SWORD aleatorio de la biblioteca y decir que estoy en el nivel 3. Debo obtener una espada oxidada con más frecuencia que la mejor espada según sus probabilidades. Si obtuve un type.SWORD de la biblioteca solicitando el nivel 10, solo obtendría la mejor espada.

Espero que esto tenga sentido.

EDIT En la etapa de inicialización, se crearán todos los objetos básicos. Cosas como las armas disponibles, armaduras, alimentos, pociones, varitas, todas las cosas básicas posibles que tienen un mosaico gráfico único en el juego. Entonces, cuando quiero colocar un objeto en alguna parte, solo hago una copia de una de las Cosas disponibles, ajusto un poco sus estadísticas y la vuelco al mundo. Los elementos reales son todos subclase de la clase raíz Cosa, como la clase Criatura, Artículo, Equipar (se extiende Artículo), Arma (amplía Equipar), Armadura (amplía Equipamiento), Comida (se extiende a Artículo), etc. Pero quiero etiquetar diferentes en la base de datos de la Biblioteca, quiero usar etiquetas adicionales, como type.RARE, type.ARTIFACT, type.CURSED, así que quiero etiquetas adicionales además de la clase.

El juego utiliza LIBGDX para estar disponible en Android y como un applet. Utilizo el conjunto de Rltile gratuito, que tiene miles de buenos mosaicos. Utilizaré Pubnub o Google App Engine para proporcionar compatibilidad con varios jugadores.

+0

ArrayList - http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html – Coffee

+0

¿Su mundo tienen una base de datos de objetos fijos presentes en la creación? ¿O son objetos creados de la nada cuando se los necesita? – sarnold

+0

por lo que cada cosa tiene un conjunto de tipos anidados? es decir, espada, arma, artículo, equipo? –

Respuesta

5

se me ocurre tres respuestas:

  1. escribir sus propios Library que almacena estas cosas en Map s con métodos personalizados. por lo que puede tener un Map<Type,List<Object>> que almacena listas de cosas por tipo y luego un método que toma un tipo, recupera la lista del mapa, y selecciona algo por probabilidad (eso es fácil de hacer - usted solo algunas arriba de las probabilidades, genere un número aleatorio entre 0 y la suma, y ​​luego camine por la lista, restando la probabilidad del ítem de su valor aleatorio hasta que sea negativo - usted devuelve el ítem que lo hizo negativo [*]). también puede filtrar la lista primero por el nivel , por ejemplo.

    si tiene una verdadera mezcla de diferentes cosas, y no desea basar esto en tipos, luego otra opción (más lento, pero más flexible) es colocar todo en una lista y luego filtrar por sus necesidades . una buena manera de hacerlo es con guayaba - vea Iterables.filter y Predicate en https://code.google.com/p/guava-libraries/. puede proporcionar una interfaz que toma un predicado y devuelve una selección aleatoria de lo que quede después del filtrado.predicados son fáciles de construir "en línea" con las clases anónimas - ver ejemplos en https://code.google.com/p/guava-libraries/wiki/FunctionalExplained#Functions_and_Predicates

  2. pegarse todo esto en una base de datos. tal vez soy demasiado emprendedor, y la gente de juegos nunca haría esto, pero me parece que una pequeña base de datos incrustada como sqlite o H2 sería perfecta para esto. a continuación, puede seleccionar cosas con consultas SQL (esta ya es una respuesta larga, así que no daré más detalles aquí).

  3. cambie su diseño. lo que describes no es muy OO. en lugar de tener tipos, sus Cosas podrían implementar interfaces. por lo que la interfaz Weapon tendría un método getMinLevel(), por ejemplo. y luego, con un diseño como este, use una base de datos con ORM (hibernación).

lo que está haciendo es una especie de ambicioso y sospecho que es más sobre el aprendizaje que cualquier otra cosa (ninguna crítica a lo previsto - así es como me entero de cosas, al hacer las cosas, por lo que sólo asumiendo que son como yo) . así que elija con lo que se sienta más cómodo.

[*] esto supone que siempre desea devolver algo. si las probabilidades están normalizadas y desea poder devolver nada, seleccione el valor inicial de 0-1 (o 0-100 si usa porcentajes). y, si nada convierte el valor en negativo cuando revisa la lista, no devuelva nada.

2

El enfoque más fácil es colocar todos los objetos en una única lista de arrays grande, y usar muestreos repetidos para seleccionar un objeto.

El procedimiento para seleccionar un elemento de azar es muy simple:

  1. Seleccione un número aleatorio entre 0 y hasta el tamaño de la ArrayList
  2. Obtener el objeto en el que el índice de la biblioteca
  3. Si el objeto no cumple con los criterios que especifique (por ejemplo, "es un tipo.SWORD or type.MACE?") volver al inicio
  4. Si el objeto está fuera del nivel mínimo o máximo, vuelva al inicio
  5. Si el obje ct tiene una rareza de menos del 100%, crea un número aleatorio de 0-100%. Si el número aleatorio excede la rareza del objeto, retroceda para comenzar. La mayoría de los objetos deberían tener una rareza de, digamos, 10-100%, si quieres objetos extremadamente comunes, entonces puedes agregarlos varias veces a la biblioteca.

Este procedimiento producirá un objeto que cumple los criterios tarde o temprano (si existe) y lo hará de acuerdo con el porcentaje de rareza.

El único truco es que se repetirá infinitamente si no existe tal objeto. Supongamos que no hay armas en la biblioteca en el nivel 17, por ejemplo. Para evitar esto, me gustaría proponer la ampliación de minLevel y maxLevel después de cada 100 intentos para garantizar que finalmente se encuentre uno. Asegúrese de tener siempre un objeto de nivel 1 de cada tipo disponible.

Por seguridad, es posible que también desee un rescate después de, digamos, 100,000 intentos (pero recuerde lanzar una excepción: ¡este es un problema si está pidiendo cosas que no existen en la biblioteca!).

P.S. Implementé un sistema de biblioteca similar en un juego roguelike llamado Tyrant que creé hace muchos años. Fuente es aquí si está interersted:

https://github.com/mikera/tyrant/blob/master/src/main/java/mikera/engine/Lib.java

+2

Es genial que hayas respondido mi pregunta Mikera. Tu juego Tyrant ha sido mi inspiración por muchos años. Es un juego tan impresionante e intrincado escrito en Java, me encanta. Mi juego de rol está usando también el conjunto rltile, pero el mío está siendo escrito para Android y un Applet, y será multijugador. Estoy tratando de evitar mirar tu código fuente, o de lo contrario robaré tu código y ideas. Yo quiero que este juego sea 100% mi propio código. Noté que recientemente cambiaste el nombre a tyrant-old en tu repositorio de código, ¿tienes algún plan para crear un tyrant 2? Eso sería tan increíble! –

+0

¡Me alegro de que haya sido útil para ti! Para que conste, realmente no me importa que robes código e ideas: ¡ese es el espíritu de código abierto después de todo! Hay una pequeña posibilidad de que pueda probar Tirano 2 (posiblemente sea una reescritura en Clojure). ¡Depende de que tenga un par de meses gratis! – mikera

Cuestiones relacionadas