Question

J'essaie de terminer un jeu de rôle pour un projet, mais je ne sais pas du tout comment créer la carte du jeu. Il n’a pas besoin d’être graphique, mais le code de la carte et de chaque mosaïque doit être correct.

Jusqu'à présent, j'ai envisagé de créer une carte non matricielle (à la demande du professeur) en utilisant une liste ArrayList contenant toutes les tuiles liées.

public abstract class Casella {
/** 
 * @uml.property name="tabellone"
 * @uml.associationEnd multiplicity="(1 1)" inverse="casella:Tabellone"
 * @uml.association name="contains"
 */

private int id;
private boolean free = true;
private List adjacent;
private List items;
private Tabellone tabellone = null;

public void in(){
    free = false;
}

public void out(){
    free = true;
}

}

C’était le code d’une seule tuile (qui a 3 classes qui l’étend) Je ne sais toujours pas comment assembler et générer une carte.

Merci pour votre temps.

Était-ce utile?

La solution 6

J'ai géré cela en utilisant des listes de contiguïté. Chaque cellule aura une ArrayList contenant les index des cellules adjacentes. Ces index sont ceux que ladite cellule a sur la carte ArrayList de cellules.

http://en.wikipedia.org/wiki/Adjacency_list

Autres conseils

Ne commencez pas par la mise en œuvre, commencez par la façon dont vous souhaitez utiliser la carte. Cela vous donnera quelques contraintes quant à la mise en œuvre. Par exemple:

Lorsque vous tracez la carte, comment y accédez-vous? Par coordonnée? Ou par "aller à l'ouest à partir de la tuile X"?

[EDIT] Je suggère de commencer par la boucle principale du jeu de rôle. Vous aurez besoin de placer le personnage / jeton quelque part (c’est-à-dire qu’il a besoin d’une sorte de relation avec une tuile).

Ensuite, vous devez déplacer le personnage. Un personnage doit pouvoir examiner la tuile actuelle (adversaires, objets, type). Il a besoin d’un moyen de savoir comment il peut bouger (c’est-à-dire qu’il ya un mur à droite?)

Ceci vous donne une interface pour votre carte: Services qu’elle rend pour les autres objets du jeu. Lorsque vous avez une idée de ce que l'interface doit fournir, cela devrait vous donner une idée de la façon d'implémenter la carte (la structure de données).

Pour générer une carte, utilisez un générateur de nombres aléatoires plus du "bon sens". Regardez les tuiles adjacentes: quand elles sont toutes des villes, cette tuile est probablement aussi une ville. Même chose pour les plaines. Les collines sont des objets singuliers et ils sont moins fréquents.

Exécutez ce code, imprimez la carte au format ASCII ("C", "P", "H", ill) pour voir si cela fonctionne.

Pour générer une carte de ce type sans utiliser de matrice, je vous recommande de commencer par une tuile centrale, puis de remplir la carte vers l’extérieur à l’aide d’un algorithme de recherche de largeur d'abord modifié. Tout d'abord, nous aurons besoin de quelque chose d'un peu mieux qu'une liste de tuiles adjacentes. Vous pouvez simplement avoir quatre variables, une pour chaque direction qui stocke la tuile suivante, en tant que telles:

private Tabellone up = null;
private Tabellone down = null;
private Tabellone left = null;
private Tabellone right = null;

Disons que nous commençons par la tuile la plus centrale. Il vous suffit maintenant de déterminer le nombre de directions nulles et de créer un nouvel objet Tablellone pour chaque direction, en veillant à définir chacune des variables de cet objet actuel et à définir la variable opposée appropriée dans l'objet créé. .

Tabellone adj = new Tabellone();
up = adj;
adj.setDown(this);

Une fois que vous avez rempli toutes les instructions sur cette vignette, vous choisissez l'une des autres vignettes que vous avez créées et effectuez la même opération. C'est là qu'intervient l'algorithme de recherche d'abord large. Vous pouvez utiliser une file d'attente pour passer en revue chaque mosaïque que vous avez créée et remplir les instructions. Pour arrêter l’algorithme, définissez simplement une limite sur le nombre de mosaïques que vous souhaitez créer et utilisez un compteur pour en suivre le nombre.

int count = 0;
ArrayList<Tabellone> queue = new ArrayList<Tabellone>()
queue.add(/*center tile*/);
while (count < 100) { //if we want 100 tiles
  //take out the center tile from the beginning of the array list, create a tile for each direction and add those tiles to the array list, then increment count by 1.
}

Remarque: Cet algorithme, dans sa version actuelle, créera une carte en forme de losange. Si vous souhaitez un carré, vous devez également définir une variable pour chaque direction diagonale.

Bien sûr, si cela vous semble un peu plus compliqué que vous ne le souhaiteriez, je recommanderais un système de coordonnées.

Les murs, les sacs et les zones sont des conteneurs spéciaux, qui contiendront tous les murs, les sacs et les zones du jeu.

private String level =
          "    ######\n"
        + "    ##   #\n"
        + "    ##$  #\n"
        + "  ####  $##\n"
        + "  ##  $ $ #\n"
        + "#### # ## #   ######\n"
        + "##   # ## #####  ..#\n"
        + "## $  $          ..#\n"
        + "###### ### #@##  ..#\n"
        + "    ##     #########\n"
        + "    ########\n";

C'est le niveau du jeu. À part l'espace, il y a cinq caractères. Le hash (#) représente un mur. Le dollar ($) représente la boîte à déplacer. Le point (.) Représente l'endroit où nous devons déplacer la boîte. Le caractère (@) est le sokoban. Et enfin, le caractère de nouvelle ligne (\ n) commence une nouvelle ligne du monde.

La vitesse ou la mémoire sont-elles une préoccupation majeure pour ce projet? Sinon, pourquoi n’utilisez-vous pas un tableau 2D?

Quelque chose comme

Casella map [][] = new Casella[xSize][ySize];

À partir de là, il est facile de conceptualiser. Imaginez-le simplement comme une feuille de calcul Excel où chaque cellule est une tuile sur la carte.

Cependant, vous allez bien, un peu difficile à conceptualiser parfois. Vous avez une liste de tuiles adjacentes. Ainsi, lors de la création de votre carte, vous commencez quelque part, éventuellement en haut à gauche, à partir de là.

Vous pouvez utiliser des boucles for imbriquées pour configurer la carte et vous aider à déterminer les éléments du bord.

for(int i = 0; i < XSIZE ; ++i)
    for(int j = 0; j < YSIZE ; ++j)
        if(j==0) //found left edge (i.e. no adjacent ones to the left)
        if(j==(YSIZE)) //found right edge (you get the picture) 

L’intérêt de l’utilisation des boucles et de la vérification des contours est que vous allez avoir besoin de relier en arrière et en avant, de haut en bas pour chaque mosaïque, sauf sur les contours, où vous aurez 2 ou 3 liens au lieu de 4.

Le code doit être correct n'est pas vraiment une exigence fonctionnelle, il est donc difficile de dire exactement ce qui est correct sans en savoir plus sur votre jeu / carte.

En supposant que votre carte soit composée de mosaïques X et qu'aucune adjacence ordonnée ne soit préférable à une solution non matricielle, une solution courante consiste à la modéliser comme un graphe en utilisant soit la liste de adjacence pour la adjacence non symétrique, soit la liste d'incidence pour la adjacence symétrique. . Si vous utilisez une liste d'incidence, vous avez besoin d'un objet d'arête contenant les sommets que l'arête connecte, si vous utilisez une liste d'adjacence, une multimap pourrait être cool à utiliser.

Si vous souhaitez une solution non matricielle avec contiguïté ordonnée, AlbertoPL a la solution pour cela.

En supposant que vous ayez une carte de largeur X mosaïque et de hauteur Y mosaïque et que les mosaïques juxtaposées soient adjacentes, de sorte que chaque mosaïque possède au maximum 4 et 2 mosaïques adjacentes au maximum, vous pouvez utiliser une matrice pour accéder aux mosaïques. et représentent également l'adjacence par l'adjacence matricielle. L'idée est que la carte [Y] [X] est adjacente à la carte [Y + 1] [X] et à la carte [Y] [X + 1] et inversement. Cette solution peut également convenir à une contiguïté maximale de 6 et 3 minimum si la mosaïque [Y + 1] [X + 1] est adjacente à la mosaïque [Y] [X]. L'avantage, c'est que vous pouvez facilement analyser la carte, et comme elle a 2 dimensions, il est naturel de la modéliser ainsi. L'inconvénient est qu'une fois qu'une tuile est définie, vous ne pouvez pas changer sa proximité sans changer la matrice. Comme ce n’est pas ce que votre professeur a suggéré, vous voudrez peut-être ne pas le faire, mais si vous avez une adjacence ordonnée (statique), cela pourrait être le moyen le plus simple de le faire.

S'il s'agit d'une carte basée sur des mosaïques, chaque pièce entretient une relation fixe avec ses pièces adjacentes. Vous n’aurez peut-être pas à vous soucier des coordonnées (bien que cela puisse être plus simple si les carreaux sont carrés), mais vous devrez vous soucier de l’orientation.

Si les carreaux sont carrés, les points cardinaux (n, s, e, w) peuvent suffire. Si ce sont des carreaux hexagonaux, vous pouvez numéroter vos sorties de 1 à 6 (éventuellement avec des constantes finales statiques). Ensuite, chaque tuile adjacente peut être liée à celle-ci avec sa sortie.

Comme le dit Aaron , vous devez d'abord décider de la façon dont les coordonnées de mappage seront.

Mais vous n'êtes pas contraint par un système de coordonnées X-Y-Z. Par exemple, chaque mosaïque peut être liée à une autre mosaïque de votre carte. Tout dépend de la façon dont vous voulez le construire.

Vous dites que vous construisez un jeu de rôle, alors vous devez avoir une bonne vue du terrain qui entoure votre personnage. Est-ce multi-niveau? Comment le personnage se déplace-t-il d'une tuile à une autre? Le mouvement est-il à sens unique?

Il existe littéralement des dizaines de questions à poser lors de la conception d’une carte pour un jeu.

Vous devez très bien planifier, avant de commencer à coder.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top