Pregunta

Estoy tratando de completar un juego de rol para un proyecto, pero no tengo idea de cómo hacer el mapa del juego. No necesita ser gráfico, pero el código para todo el mapa y cada mosaico debe ser correcto.

Hasta ahora, pensé en hacer un mapa no matricial (como lo solicitó el profesor) usando una ArrayList que contiene todos los mosaicos vinculados.

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;
}

}

Este fue el código para un único mosaico (que tiene 3 clases que lo extiende). Todavía no tengo idea de cómo armar y generar un mapa.

Gracias por su tiempo.

¿Fue útil?

Solución 6

Lo logré usando listas de adyacencia. Cada celda tendrá una ArrayList que contiene los índices de las celdas adyacentes. Esos índices son los que dicha celda tiene en el mapa ArrayList de celdas.

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

Otros consejos

No comience con la implementación, comience con cómo le gustaría usar el mapa. Eso le dará algunas restricciones sobre cómo implementarlo. Por ejemplo:

Al dibujar el mapa, ¿cómo se accede a él? Por coordenadas? O bien, vaya al oeste desde el mosaico X

[EDITAR] Sugiero comenzar con el bucle principal del juego de rol. Tendrá que colocar el personaje / ficha en algún lugar (es decir, necesita algún tipo de relación con un mosaico).

Entonces necesitas mover el personaje. Un personaje debe poder examinar el mosaico actual (oponentes, elementos, tipo). Necesita una forma de saber cómo puede moverse (es decir, ¿hay un muro a la derecha?)

Esto le proporciona una interfaz para su mapa: servicios que presta para otros objetos en el juego. Cuando tenga una idea de lo que debe proporcionar la interfaz, eso debería darle una idea de cómo implementar el mapa (la estructura de datos).

En cuanto a la generación de un mapa, use un generador de números aleatorios más algo de "sentido común". Echa un vistazo a las fichas adyacentes: cuando todas son de ciudad, esta ficha también es probablemente ciudad. Lo mismo para las llanuras. Las colinas son elementos singulares, y son menos frecuentes.

Ejecute este código, imprima el mapa como ASCII (" C " ity " P " lain " H " ill) para ver si funciona.

Para generar un mapa como este sin usar una matriz, recomiendo comenzar con un mosaico central y luego llenar el mapa hacia afuera usando un algoritmo de búsqueda de amplitud modificado primero. En primer lugar, necesitaremos algo un poco mejor que una lista de mosaicos adyacentes. Simplemente podría tener cuatro variables, una para cada dirección que almacena el siguiente mosaico, como tal:

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

Digamos que comenzamos con el mosaico más central. Todo lo que tiene que hacer ahora es calcular cuántas direcciones son nulas y crear un nuevo objeto Tablellone para cada dirección, asegurándose de establecer cada una de las variables en este objeto actual y establecer la variable opuesta apropiada en el objeto creado .

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

Una vez que haya completado todas las instrucciones en este mosaico, elija uno de los otros mosaicos que ha creado y realice la misma operación. Aquí es donde entra en juego el algoritmo de búsqueda de amplitud. Puede usar una cola para recorrer cada mosaico que ha creado y completar las instrucciones. Para detener el algoritmo, simplemente establezca un límite en la cantidad de mosaicos que desea crear y use un contador para realizar un seguimiento de cuántos se han creado.

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.
}

Nota: este algoritmo en su forma actual creará un mapa en forma de diamante, si desea un cuadrado, también necesitaría tener una variable para cada dirección diagonal.

Por supuesto, si esto parece un poco más complicado de lo que quisiera, recomendaría un sistema de coordenadas.

Las paredes, bolsas y áreas son recipientes especiales, que contendrán todas las paredes, bolsas y áreas del juego.

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

Este es el nivel del juego. Excepto por el espacio, hay cinco caracteres. El hash (#) representa una pared. El dólar ($) representa la caja para mover. El carácter de punto (.) Representa el lugar donde debemos mover el cuadro. El carácter at (@) es el sokoban. Y finalmente el nuevo carácter de línea (\ n) comienza una nueva fila del mundo.

¿Es la velocidad o la memoria una gran preocupación para este proyecto? Si no, ¿por qué no usas una matriz 2d?

Algo así

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

Desde aquí es fácil conceptualizar, simplemente imagínelo como una hoja de cálculo de Excel donde cada celda es un mosaico en el mapa.

Sin embargo, el camino por el que vas está bien, pero a veces es un poco difícil de conceptualizar. Tienes una Lista de fichas adyacentes. Entonces, al crear su mapa, comienza en algún lugar, posiblemente arriba a la izquierda, y continúa desde allí.

Podría usar bucles anidados para configurar el mapa y ayudar a determinar los elementos de borde.

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) 

El punto de usar los bucles y verificar los bordes es que necesitará vincular hacia atrás y hacia adelante, hacia arriba y hacia abajo para cada mosaico, excepto en los bordes, donde tendrá 2 o 3 enlaces en lugar de 4.

El código debe ser correcto realmente no es un requisito funcional, por lo que es difícil decir exactamente lo que es correcto sin saber más sobre su juego / mapa.

Suponiendo que tiene un mapa que tiene mosaicos X y sin adyacencia ordenada, una solución no matricial es la mejor, una solución común es simplemente modelarlo como un gráfico usando una lista de adyacencia para adyacencia no simétrica o una lista de incidencia para adyacencia simétrica . Si está usando una lista de incidencia, necesita un objeto de borde que contenga los vértices que el borde está conectando, si está usando una lista de adyacencia a multimap puede ser genial de usar.

Si desea una solución no matricial con adyacencia ordenada, AlbertoPL tiene la solución para eso.

Suponiendo que tiene un mapa que tiene X mosaicos de ancho e Y mosaicos de alto y los mosaicos que están uno al lado del otro son adyacentes, de modo que cada mosaico tiene un máximo de 4 y mínimo 2 mosaicos adyacentes, puede usar una matriz para acceder a los mosaicos y también representan adyacencia por adyacencia matricial. La idea es que el mapa [Y] [X] sea adyacente al mapa [Y + 1] [X] y al mapa [Y] [X + 1] y viceversa. Esta solución también podría ajustarse a una adyacencia máxima de 6 y 3 min si la casilla [Y + 1] [X + 1] está adyacente a la casilla [Y] [X]. Lo bueno de esto es que puede analizar fácilmente el mapa, y dado que tiene 2 dimensiones, es natural modelarlo así. Lo malo es que una vez que se establece un mosaico, no puede cambiar su adyacencia sin cambiar la matriz. Como esto no es lo que sugirió su profesor, es posible que no quiera hacerlo, pero si tiene adyacencia ordenada (estática), esta podría ser la forma más fácil de hacerlo.

Si se trata de un mapa basado en mosaicos, cada habitación tiene una relación fija con sus habitaciones adyacentes. Es posible que no deba preocuparse por las coordenadas (aunque podría ser más simple si los cuadros son cuadrados), pero deberá preocuparse por las instrucciones.

Si las fichas son cuadradas, las direcciones cardinales (n, s, e, w) pueden ser todo lo que necesita. Si son fichas hexadecimales, puede numerar sus salidas 1-6 (tal vez con constantes finales estáticas). Luego, cada ficha adyacente se puede vincular a esta junto con su salida.

Como dijo Aaron , primero debe decidir cómo serán las coordenadas de mapeo.

Pero no está limitado por un sistema de coordenadas X-Y-Z. Por ejemplo, cada mosaico podría estar vinculado a cualquier otro mosaico en su mapa. Todo depende de cómo quieras construirlo.

Dices que estás construyendo un juego de rol, entonces necesitas tener una buena vista del terreno que rodea a tu personaje. ¿Es multinivel? ¿Cómo se mueve el personaje de una ficha a otra? ¿El movimiento es unidireccional?

Hay, literalmente, docenas de preguntas que hacer al diseñar un mapa para un juego.

Primero debe planificarlo muy bien, antes de comenzar a codificar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top