Domanda

Sto cercando di completare un gioco di ruolo per un progetto, ma non ho idea di come realizzare la mappa del gioco. Non deve essere grafico, ma il codice per l'intera mappa e ogni riquadro deve essere corretto.

Finora, ho pensato di creare una mappa non matrimoni (come richiesto dal professore) usando una ArrayList che contiene tutte le tessere collegate.

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

}

Questo era il codice per un singolo riquadro (che ha 3 classi che lo estendono). Non ho ancora idea di come mettere insieme e generare una mappa.

Grazie per il tuo tempo.

È stato utile?

Soluzione 6

L'ho gestito usando gli elenchi di adiacenza. Ogni cella avrà un ArrayList contenente gli indici delle celle adiacenti. Tali indici sono quelli che detta cella ha nella mappa ArrayList of cells.

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

Altri suggerimenti

Non iniziare con l'implementazione, inizia con il modo in cui desideri utilizzare la mappa. Ciò ti darà alcuni vincoli su come implementarlo. Ad esempio:

Quando si disegna la mappa, come si accede ad essa? Per coordinate? O di " vai a ovest dalla tessera X " ;?

[EDIT] Suggerisco di iniziare con il ciclo principale del gioco di ruolo. Dovrai posizionare il personaggio / token da qualche parte (cioè ha bisogno di un qualche tipo di relazione con una tessera).

Quindi devi spostare il personaggio. Un personaggio deve essere in grado di esaminare la tessera corrente (avversari, oggetti, tipo). Ha bisogno di un modo per sapere come può muoversi (cioè c'è un muro a destra?)

Questo ti dà un'interfaccia per la tua mappa: servizi che rende per altri oggetti nel gioco. Quando hai un'idea di ciò che l'interfaccia deve fornire, questo dovrebbe darti un'idea su come implementare la mappa (la struttura dei dati).

Per quanto riguarda la generazione di una mappa, usa un generatore di numeri casuali più un po 'di "buon senso". Dai un'occhiata alle tessere adiacenti: quando sono tutte città, anche questa tessera è probabilmente città. Lo stesso vale per le pianure. Le colline sono oggetti singolari e sono meno frequenti.

Esegui questo codice, stampa la mappa come ASCII (" C " ity, " P " lain, " H " ill) per vedere se funziona.

Per generare una mappa come questa senza usare una matrice, ti consiglio di iniziare con una tessera centrale e quindi di popolare la mappa verso l'esterno usando un primo algoritmo di ricerca con ampiezza modificata. Prima di tutto, avremo bisogno di qualcosa di leggermente migliore di un elenco di tessere adiacenti. Potresti semplicemente avere quattro variabili, una per ogni direzione in cui è memorizzata la tessera successiva, come tale:

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

Supponiamo che iniziamo con il riquadro più centrale. Tutto quello che devi fare ora è capire quante delle direzioni sono nulle e creare un nuovo oggetto Tablellone per ogni direzione, assicurandoti di impostare ciascuna delle variabili in questo oggetto corrente e di impostare la variabile opposta appropriata nell'oggetto creato .

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

Dopo aver compilato tutte le indicazioni su questa tessera, scegli una delle altre tessere che hai creato ed esegui la stessa operazione. È qui che arriva l'algoritmo di ricerca breadth-first. Puoi usare una coda per passare attraverso ogni riquadro che hai creato e compilare le indicazioni. Per interrompere l'algoritmo, è sufficiente impostare un limite al numero di riquadri che si desidera creare e utilizzare un contatore per tenere traccia di quanti sono stati creati.

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: questo algoritmo così com'è creerà una mappa a forma di diamante, se vuoi un quadrato, dovrai avere anche una variabile per ogni direzione diagonale.

Naturalmente, se questo sembra un po 'più complicato di quanto vorresti, consiglierei un sistema di coordinate.

I muri, i bagagli e le aree sono contenitori speciali, che terranno tutti i muri, i bagagli e le aree del gioco.

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

Questo è il livello del gioco. Tranne lo spazio, ci sono cinque personaggi. L'hash (#) sta per un muro. Il dollaro ($) rappresenta la casella da spostare. Il carattere punto (.) Rappresenta il luogo in cui dobbiamo spostare la casella. Il carattere at (@) è il sokoban. E infine il nuovo carattere di linea (\ n) inizia una nuova riga del mondo.

La velocità o la memoria è una grande preoccupazione per questo progetto? In caso contrario, perché non usi un array 2d?

Qualcosa di simile

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

Da qui è facile concettualizzare, basta immaginarlo come un foglio di calcolo Excel in cui ogni cella è una tessera sulla mappa.

Il modo in cui stai andando va bene però, solo un po 'difficile concettualizzare a volte. Hai un elenco di tessere adiacenti. Quindi, quando crei la tua mappa, inizi da qualche parte, possibilmente in alto a sinistra, e vai da lì.

È possibile utilizzare nidificato per loop per impostare la mappa e per aiutare a determinare gli elementi del bordo.

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) 

Il punto di usare i loop e controllare i bordi è che dovrai collegarti avanti e indietro, su e giù per ogni riquadro tranne che sui bordi, dove avrai 2 o 3 collegamenti invece di 4.

Il codice deve essere corretto in realtà non è un requisito funzionale, quindi è difficile dire esattamente cosa è corretto senza sapere di più sul tuo gioco / mappa.

Supponendo che tu abbia una mappa con X tessere e nessuna adiacenza ordinata è la soluzione non-matrimoni è la migliore, una soluzione comune è semplicemente modellarla come un grafico usando una lista di adiacenza per adiacenza non simmetrica o una lista di incidenza per adiacenza simmetrica . Se si utilizza un elenco di incidenza, è necessario un oggetto edge che contenga i vertici a cui si connette il edge, se si utilizza un elenco di adiacenza a multimap potrebbe essere interessante da usare.

Se vuoi una soluzione non-matriariale con adiacenza ordinata, AlbertoPL ha la soluzione per questo.

Supponendo che tu abbia una mappa larga X tessere e Y alta e le tessere una accanto all'altra siano adiacenti, in modo che ogni tessera abbia al massimo 4 e min 2 tessere adiacenti puoi usare una matrice per accedere alle tessere e rappresentano anche adiacenza per adiacenza matrimoniale. L'idea è che la mappa [Y] [X] sia adiacente alla mappa [Y + 1] [X] e alla mappa [Y] [X + 1] e viceversa. Questa soluzione potrebbe anche adattarsi ad un massimo di 6 e 3 min adiacenti se il riquadro [Y + 1] [X + 1] è adiacente al riquadro [Y] [X]. Il vantaggio è che puoi facilmente analizzare la mappa e poiché ha 2 dimensioni è naturale modellarla in questo modo. Il rovescio della medaglia è che una volta impostata una tessera, non puoi cambiare la sua adiacenza senza cambiare la matrice. Poiché questo non è ciò che il tuo professore ha suggerito, potresti non volerlo fare, ma se hai un'adiacenza ordinata (statica), questo potrebbe essere il modo più semplice per farlo.

Se si tratta di una mappa basata su piastrelle, ogni stanza ha una relazione fissa con le sue stanze adiacenti. Potrebbe non essere necessario preoccuparsi delle coordinate (anche se potrebbe essere più semplice se le tessere sono quadrate), ma dovrai preoccuparti delle direzioni.

Se le tessere sono quadrate, le direzioni cardinali (n, s, e, w) potrebbero essere tutto ciò di cui hai bisogno. Se sono tessere esadecimali, puoi numerare le tue uscite 1-6 (forse con costanti finali statiche). Quindi ogni tessera adiacente può essere collegata a questa insieme alla sua uscita.

Come detto da Aaron , devi prima decidere come saranno le coordinate della mappa.

Ma non sei vincolato da un sistema di coordinate X-Y-Z. Ad esempio, ogni riquadro può essere collegato a qualsiasi altro riquadro sulla mappa. Tutto dipende da come vuoi costruirlo.

Dici che stai costruendo un gioco di ruolo, quindi devi avere una buona visione del terreno che circonda il tuo personaggio. È multilivello? Come si sposta il personaggio da una tessera all'altra? Il movimento è a senso unico?

Ci sono letteralmente dozzine di domande da porre quando si progetta una mappa per un gioco.

Devi pianificarlo molto bene prima di iniziare a scrivere codice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top