Qu'est-ce qu'une bonne structure de données Java pour stocker des éléments de jeu RPG?


Je construis un jeu de donjon RPG en Java et je suis bloqué sur la création d'une structure de données.

J'ai beaucoup d'objets de chose que je peux copier pour remplir un donjon avec. Par exemple, il y a un objet de Chose de pain, et un objet de Chose d'épée, un objet de Chose de cotte de mailles, et des Choses de monstre, etc. Je veux les stocker dans une bibliothèque centrale, puis pouvoir récupérer un objet à l'aide de certaines requêtes. Je veux les stocker en utilisant les champs suivants:

int minLevel
int maxLevel
double probability
int[] types

Donc une épée rouillée serait avoir un minLevel de 1, maxLevel de 3, un probability de la rareté(3%),et [type.SWORD,type.WEAPON,type.ITEM,TYPE.EQUIP]. Une meilleure épée aurait minLevel 2, maxLevel 10, la rareté (1%).

Ensuite, je veux récupérer un type.SWORD aléatoire de la bibliothèque et dire que je suis au niveau 3. Je devrais avoir une épée rouillée plus souvent que la meilleure épée en fonction de leurs probabilités. Si je récupérais un type.SWORD de la bibliothèque demandant le niveau 10, je ne récupérerais que la meilleure épée.

J'espère que cela a du sens.

MODIFIER Lors de l'initialisation étape, tous les objets de base seront créés. Des choses comme les armes disponibles, armures, aliments, potions, baguettes, toutes les choses possibles de base qui ont une tuile graphique unique dans le jeu. Ensuite, quand je veux placer un objet quelque part, je fais juste une copie de l'une des choses disponibles, j'ajuste un peu ses statistiques et je le plonge dans le monde. Les objets réels sont tous sous-classe de la classe racine Chose, tels que la classe Créature, Item, Equip (étend Item), Weapon (étend Equip),Armor (étend Équipez), Nourriture (étend l'article), etc. Mais je veux les marquer différemment dans la base de données de la bibliothèque, je veux utiliser des balises supplémentaires, telles que type.RARE, type.ARTEFACT, type.MAUDIT, donc je veux des balises supplémentaires en plus de la classe.

Le jeu utilise LIBGDX pour être disponible sur Android et en tant qu'Applet. J'utilise l'ensemble Rltile gratuit, qui a des milliers de bonnes tuiles. Je vais utiliser Pubnub ou Google App Engine pour fournir un support multijoueur.

Author: Brian Tompsett - 汤莱恩, 2012-04-01

2 answers

Je peux penser à trois réponses:

  1. Rédiger votre propre Library qui stocke ces choses dans Maps avec des méthodes personnalisées. vous pourriez donc avoir un {[2] } qui stocke des listes d'objets par type et puis une méthode qui prend un type, récupère la liste de la carte et sélectionne quelque chose par probabilité (c'est facile à faire-vous avez juste quelques probabilités, générez un nombre aléatoire entre 0 et la somme, puis parcourez la liste, soustraire la probabilité de l'élément de votre aléatoire valeur jusqu'à ce qu'il soit négatif-vous retourner l'article qui l'a rendu négatif[*]). vous pouvez également filtrer la liste en premier par niveau, par exemple.

    Si vous avez un vrai mélange de choses différentes, et que vous ne voulez pas baser cela sur des types, ensuite, une autre option (plus lente, mais plus flexible) consiste à tout placer dans une liste et puis filtrer par vos besoins. une belle façon de le faire est avec la goyave - voir Iterables.filter et Predicate à https://code.google.com/p/guava-libraries/. vous pouvez fournir une interface qui prend un prédicat et renvoie un hasard sélection de tout ce qui reste après le filtrage. les prédicats sont faciles à construire "inline" avec des classes anonymes-voir des exemples à https://code.google.com/p/guava-libraries/wiki/FunctionalExplained#Functions_and_Predicates

  2. Collez tout cela dans une base de données. peut-être que je suis trop entreprenant, et les gens de jeux le feraient ne jamais faire cela, mais il me semble qu'une petite base de données intégrée comme sqlite ou H2 serait parfait pour cela. vous peut ensuite sélectionner des choses avec des requêtes SQL (ceci est déjà une longue réponse, donc je ne donnerai pas plus de détails ici).

  3. Changer votre conception. ce que vous décrivez n'est pas très OO. au lieu d'avoir des types, vos choses pourraient implémenter des interfaces. donc, l'interface Weapon aurait un getMinLevel() méthode, par exemple. et puis, avec un design comme celui-ci, utilisez un base de données avec l'ORM (hibernate).

Ce que vous faites est un peu ambitieux et je soupçonne qu'il s'agit plus d'apprendre que toute autre chose (aucune critique prévue - c'est comme ça que j'apprends des choses, en faisant des choses, donc en supposant que vous êtes comme moi). alors choisissez celui avec lequel vous vous sentez le plus à l'aise.

[*] cela suppose que vous voulez toujours retourner quelque chose. si les probabilités sont normalisées et que vous souhaitez ne rien renvoyer, sélectionnez la valeur initiale de 0-1 (ou 0-100 si vous utilisez des pourcentages). et, si rien ne tourne la valeur négative lorsque vous parcourez la liste, ne retournez rien.

 5
Author: andrew cooke, 2012-04-01 07:17:44

L'approche la plus simple consiste à placer tous vos objets dans une seule grande liste de tableaux et à utiliser un échantillonnage répété pour sélectionner un objet.

La procédure pour sélectionner un élément aléatoire est très simple:

  1. Sélectionnez un nombre aléatoire de 0 jusqu'à la taille de l'ArrayList
  2. Obtenir l'objet à cet index de la bibliothèque
  3. Si l'objet ne répond pas aux critères que vous spécifiez (par exemple "est de type a.ÉPÉE ou type.MACE?") revenir au début
  4. Si l'objet est en dehors du niveau minimum ou maximum, retour au début
  5. Si l'objet a une rareté inférieure à 100%, créez un nombre aléatoire de 0 à 100%. Si le nombre aléatoire dépasse la rareté de l'objet, faites une boucle pour démarrer. La plupart des objets devraient avoir une rareté de disons 10-100%, si vous voulez des objets extrêmement communs, vous pouvez les ajouter plusieurs fois à la bibliothèque.

Cette procédure produira un objet qui répond tôt ou tard aux critères (s'il existe) et le fera en fonction de la rareté pourcentage.

La seule petite astuce est qu'il boucle infiniment si un tel objet n'existe pas. Supposons qu'il n'y ait pas d'arme dans la bibliothèque au niveau 17 par exemple? Pour contourner cela, je proposerais d'élargir le minLevel et le maxLevel après chaque 100 essais pour s'assurer que finalement on en trouve un. Assurez-vous d'avoir toujours un objet de niveau 1 de chaque type disponible.

Pour des raisons de sécurité, vous voudrez peut-être également un plan de sauvetage après 100 000 essais (mais n'oubliez pas de lancer une exception-c'est un problème si vous demandez des choses qui n'existent pas dans la bibliothèque!).

PS J'ai implémenté un système de bibliothèque similaire dans un jeu roguelike appelé Tyrant que j'ai créé il y a de nombreuses années. La source est ici si vous êtes intéressé:

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

 2
Author: mikera, 2012-04-01 01:34:37