¿Cómo puedo definir elementos en mi juego de rol como Java?

21

Estoy trabajando casualmente en un juego de tipo RPG en Java, pero tengo problemas para descubrir cómo puedo tener elementos que puedan hacer muchas cosas diferentes sin crear una clase diferente para cada elemento.

Como ejemplo, ¿cómo crearía un hacha que pudiera cortar árboles y atacar monstruos?

Si extiendo el corte o la clase de arma, entonces no puedo extender la otra clase.

Si tengo que cortar y el arma es una interfaz, tendré mucho código duplicado cuando una daga también puede atacar a los monstruos y un hacha diferente puede cortar árboles.

Espero que haya una manera de tener una sola clase de Ítem y cargar los ítems y sus respectivas habilidades desde un archivo. Si eso es posible, ¿cómo se puede hacer? Si no es así, ¿cuál es la mejor manera de tener elementos en un juego?

MESLewis
fuente

Respuestas:

15

La respuesta de Gregory Weir es mi favorita sobre cómo estructurar las instancias de elementos para realizar múltiples roles.

Para cargar desde un archivo:

Primero, usa YAML. YAML es un lenguaje de descripción de datos con características; puede ser analizado relativamente rápido, leído y editado por humanos, admite datos binarios y existen bibliotecas para la mayoría de los lenguajes de programación, incluido Java. Esto resuelve el "¿cómo obtengo datos de archivos en objetos?"

En segundo lugar, use el patrón de peso mosca . La mayoría de los datos que lees de esos archivos son estáticos. No va a cambiar por instancia ("el hacha hace 1d10 de daño base y rompe madera pero no piedra", eso es cierto para las cinco hachas que tiene un jugador). Lo que realmente lee de los archivos YAML son estas definiciones platónicas, y sus instancias de elementos individuales tienen referencias sin propiedad (y constantes) a estas, junto con datos por instancia como "¿Cuántos cambios antes de romper?", "¿Dio el jugador me un nombre personalizado? ", y así sucesivamente.

Al compartir los datos de instancias cruzadas en un solo objeto, conserva mucha memoria y facilita la actualización de elementos sin un estado de juego persistente (guardar juegos o la base de datos de jugadores).

Entonces la estructura de tu clase se parece a:

  • Elemento de clase: una instancia por elemento
    • Posee una instancia de arma
    • Posee una instancia de herramienta
    • Tiene un nombre personalizado, etc.
  • arma de clase: (hasta) una instancia por elemento
    • Es un elemento de componente
    • Se refiere al arma Def
    • Tiene un nivel de encantamiento adicional, etc.
  • Herramienta de clase: (hasta) una instancia por elemento
    • Es un elemento de componente
    • Se refiere a ToolDef
    • Tiene una durabilidad, etc.
  • clase WeaponDef: una instancia por tipo de arma
    • Leer de un archivo, los campos deben ser constantes.
    • Tiene una cantidad de daño base, 1 o 2 manos, etc.
  • clase ToolDef: una instancia por tipo de herramienta
    • Leer de un archivo, los campos deben ser constantes.
    • Tiene una durabilidad base, materiales que puede romper, etc.
Marko Zajc
fuente
18

El patrón de diseño Componente (no compuesto) es excelente para este propósito: http://gameprogrammingpatterns.com/component.html

Básicamente, un Axe sería una instancia de la clase Item que contenía un WeaponComponent y un ToolComponent (quizás). Para probar si algo se puede usar como arma, verifique si tiene un Componente de Arma adjunto, y luego hable con esa instancia de Componente de Arma para obtener la información del arma del elemento.

Cargar desde un archivo es un ejercicio separado, por supuesto.

Gregory Avery-Weir
fuente
Y, por supuesto, una vez que tenga componentes, puede hacer un buen uso de las interfaces nuevamente. Su tipo Axe puede implementar IChopper e IWeapon, pero luego puede exponer el comportamiento del componente, lo que le permite reutilizar tanto el tipo como la implementación según sea necesario y eliminar la prueba de componentes. Si todos los ejes tienen las mismas capacidades pero diferentes estadísticas, entonces eres dorado. Si necesita elementos para tener habilidades únicas, es posible que necesite implementar una colección de componentes del juego y que sus rutinas de actualización consulten a los objetos qué pueden hacer a través de qué componentes están presentes.
CodexArcanum
66
@CodexArcanum: "Su tipo Axe puede implementar IChopper e IWeapon pero luego puede exponer el comportamiento del componente" - ¿Cuál es el punto de esto? Simplemente hincha tu jerarquía de clases. El punto del patrón de componentes es que no necesita una clase Axe o una interfaz IChopper o una interfaz IWeapon, solo componentes concretos de Chopper y Arma, y ​​un Artículo de nivel superior.
Actualmente estoy trabajando en un sistema de componentes para mis elementos de juego, y realmente solo tengo una queja importante sobre cómo se usa el patrón. Dados los componentes de Arma, Ropa y Consumible, un artículo podría estar "corrupto" teóricamente en términos de artículos que no pueden ser tanto Armas como Ropa, o una Ropa que también es Consumible. Lógicamente, un elemento solo puede ser un "Componente principal", pero al restringir los componentes está rompiendo la necesidad de un sistema de componentes en conjunto. Por lo tanto, uno de los defectos fundamentales con un sistema asombroso
Krythic