2009-06-22 3 views
3

Ich versuche, ein RPG-Spiel für ein Projekt zu vervollständigen, habe aber keine Ahnung, wie man die Spielkarte erstellt. Es muss nicht grafisch sein, aber der Code für die gesamte Karte und jede Kachel muss korrekt sein.Wie erstelle ich eine Karte in Java?

Bis jetzt dachte ich darüber nach, eine nicht-matrikulare Karte (wie vom Professor gewünscht) mit einer ArrayList zu erstellen, die alle verknüpften Kacheln enthält.

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

} 

Dies war der Code für eine einzelne Kachel (die drei Klassen hat, die sie erweitert). Ich habe immer noch keine Idee, wie man eine Karte zusammenstellt und erstellt.

Vielen Dank für Ihre Zeit.

+0

Können Sie uns mehr Details geben, was dieses Spiel ist und welche Art von Karte Sie sprechen? Eine Weltkarte mit interessanten Orten? – akarnokd

+0

Die Karte wird jedes Spiel generiert. Es ist nur eine Ebene und jede Zelle kann eine von 3 verschiedenen Arten sein (Stadt, Hügel, Ebene). Jede Zelle kann auch einen Gegenstand (Klasse Gegenstand) enthalten, der auch von 4 verschiedenen Arten sein kann. Der Charakter bewegt sich pro Zug um 1 Karte. – Gurzo

Antwort

1

Ich schaffte dies mit Adjazenzlisten. Jede Zelle hat eine ArrayList, die die Indizes der benachbarten Zellen enthält. Diese Indizes sind diejenigen, die die Zelle in der Map-Array-Liste von Zellen hat.

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

9

Beginnen Sie nicht mit der Implementierung, beginnen Sie mit der Verwendung der Karte. Das wird Ihnen einige Einschränkungen bei der Implementierung geben. Zum Beispiel:

Wie können Sie beim Zeichnen der Karte darauf zugreifen? Nach Koordinate? Oder mit "gehe nach Westen von Fliese X"?

[EDIT] Ich schlage vor, mit der Hauptschleife des RPG-Spiels zu beginnen. Du musst das Zeichen/Token irgendwo platzieren (d. H. Es benötigt irgendeine Art von Beziehung zu einer Kachel).

Dann müssen Sie das Zeichen verschieben. Ein Charakter muss in der Lage sein, die aktuelle Kachel (Gegner, Gegenstände, Typ) zu untersuchen. Es braucht einen Weg zu wissen, wie es sich bewegen kann (d. H. Gibt es eine Wand rechts?)

Dies gibt Ihnen eine Schnittstelle für Ihre Karte: Dienste, die es für andere Objekte im Spiel darstellt. Wenn Sie eine Vorstellung davon haben, was die Schnittstelle zu bieten hat, sollten Sie eine Vorstellung davon bekommen, wie Sie die Karte (die Datenstruktur) implementieren.

Verwenden Sie für das Generieren einer Karte einen Zufallszahlengenerator plus "common sense". Sieh dir die angrenzenden Kacheln an: Wenn sie alle Stadt sind, ist diese Kachel wahrscheinlich auch Stadt. Gleiches gilt für Ebenen. Hügel sind Einzelstücke, und sie sind am wenigsten häufig.

Führen Sie diesen Code aus, drucken Sie die Karte als ASCII ("C" ity, "P", "H" ill), um zu sehen, ob es funktioniert.

+0

Ich habe keine Ahnung davon. Ich denke, dass die Art, wie ich es gemacht habe, keine Coords erfordert, weil jede Kachel eine eindeutige ID hat. Aber vielleicht ist besser mit Koordinaten, ich weiß wirklich nicht ... =/ Ihr Vorschlag? – Gurzo

+1

Dies ist der Grund, warum Sie nicht wissen, wie Sie anfangen sollen. Du musst dich wirklich hinsetzen und deine Klasse benutzen, auch wenn sie noch nicht existiert. –

+0

Sie werden unabhängig von Koordinaten brauchen, sonst haben Sie nur eine Reihe von Spielkacheln, die in keiner Weise miteinander verwandt sind. Denken Sie an ein Schachbrett: Jede Kachel (Quadrat) hat eine bestimmte Koordinate, und die Beziehungen zwischen ihnen sind bekannt und behoben. – GalacticCowboy

0

Wenn es sich um eine Kachel-basierte Karte handelt, hat jedes Zimmer eine feste Beziehung zu seinen angrenzenden Räumen. Sie müssen sich möglicherweise keine Gedanken über die Koordinaten machen (obwohl es einfacher sein könnte, wenn die Kacheln quadratisch sind), aber Sie müssen sich Gedanken über die Richtung machen.

Wenn die Kacheln quadratisch sind, können Himmelsrichtungen (n, s, e, w) alles sein, was Sie brauchen. Wenn sie Hex-Kacheln sind, können Sie Ihre Exits 1-6 nummerieren (vielleicht mit statischen Endkonstanten). Dann kann jedes angrenzende Plättchen mit diesem zusammen mit seinem Ausgang verbunden werden.

+0

Die Idee der Hexenkacheln könnte das sein, wonach ich gesucht habe. Es wird also keine rechteckige Karte erzeugen (da der Professor keine solche wünscht). Wie erzeuge ich so etwas? – Gurzo

0

Wie von Aaron gesagt, müssen Sie zuerst entscheiden, wie die Maping-Koordinaten sein werden.

Aber Sie sind nicht durch ein X-Y-Z-Koordinatensystem eingeschränkt. Zum Beispiel könnte jede Kachel mit einer anderen Kachel auf Ihrer Karte verknüpft werden. Alles hängt davon ab, wie Sie es erstellen möchten.

Sie sagen, dass Sie ein RPG-Spiel erstellen, dann müssen Sie eine gute Sicht auf das Gelände rund um Ihren Charakter haben. Ist es Multi-Level? Wie bewegt sich der Charakter von einer Kachel zur nächsten? Ist die Bewegung in eine Richtung?

Es gibt buchstäblich Dutzende von Fragen zu stellen, wenn Sie eine Karte für ein Spiel entwerfen.

Sie müssen es zuerst sehr gut planen, bevor Sie mit dem Codieren beginnen.

+0

Es ist ein sehr einfaches RPG. Eine Karte, töte jeden Gegner auf der Karte und du gewinnst. Keine Stufe höher, aber Sie können neue Gegenstände auf dem Weg bekommen. Bewegung kann 1 Spielstein pro Spielzug sein. – Gurzo

1

Ist Geschwindigkeit oder Speicher ein großes Problem für dieses Projekt? Wenn nicht, warum benutzt du kein 2D-Array?

So etwas wie

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

Von hier aus ist es leicht zu konzeptionieren, Bild, um es nur als Excel-Tabelle, wobei jede Zelle eine Kachel auf der Karte ist.

Die Art, wie Sie gehen, ist in Ordnung, nur ein wenig schwer zu verstehen, manchmal. Sie haben eine Liste benachbarter Kacheln. Also, wenn Sie Ihre Karte erstellen, beginnen Sie irgendwo, möglicherweise oben links, und gehen von dort aus.

Sie könnten geschachtelte for-Schleifen verwenden, um die Karte einzurichten und die Kantenelemente zu bestimmen.

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) 

Der Punkt der Loops und die Kanten überprüft, ist, dass Sie außer an den Rändern für jede Kachel verbinden rückwärts und vorwärts, nach oben und unten gehen zu müssen, wo man entweder wird 2 oder 3 Links statt 4.

+2

Bemerkung: Sie werden niemals j == YSIZE true bekommen. Du meintest j == YSIZE - 1? – akarnokd

+0

Geschwindigkeit oder Speicher sind kein Problem, da es sich nur um ein Laborprojekt handelt. Die Verwendung eines Arrays ist sicher der ideale und einfachste Weg, aber mein Professor will keine rechteckige (auf einer Matrix basierende) Karte.Wie auch immer, wenn ich keinen anderen Weg finde, bleibe ich wahrscheinlich dabei und hoffe, dass es ihm nicht so wichtig ist. – Gurzo

+0

Danke kd304, verpasst das :) – amischiefr

3

Um eine Karte wie diese zu erstellen, ohne eine Matrix zu verwenden, empfehle ich, mit einem mittleren Kachel zu beginnen und dann die Karte mit einem modifizierten ersten Suchalgorithmus nach außen zu füllen. Zuallererst brauchen wir etwas, das ein bisschen besser ist als eine Liste der angrenzenden Kacheln. Sie könnten einfach vier Variablen, eine für jede Richtung, die die nächste Kachel, als solche speichert:

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

sagen wir mit der Mitte-die meisten Fliesen beginnen. Alles, was Sie jetzt tun müssen, ist herauszufinden, wie viele der Richtungen Null sind, und ein neues Tabellone-Objekt für jede Richtung zu erstellen. Stellen Sie sicher, dass jede Variable in diesem aktuellen Objekt gesetzt ist und die entsprechende entgegengesetzte Variable im erstellten Objekt gesetzt wird .

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

Sobald Sie alle Anweisungen auf dieser Fliese ausgefüllt haben, wählen Sie dann eine der anderen Fliesen, die Sie erstellt haben und die gleiche Operation durchführen. Hier kommt der Breiten-Suchalgorithmus ins Spiel. Sie können eine Warteschlange verwenden, um jede von Ihnen erstellte Kachel durchzugehen und die Anweisungen auszufüllen. Um den Algorithmus zu stoppen, legen Sie einfach die Anzahl der zu erstellenden Kacheln fest und verwenden Sie einen Zähler, um zu verfolgen, wie viele Kacheln erstellt wurden.

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

Hinweis: Dieser Algorithmus, da es eine rautenförmige Karte wird schaffen steht, wenn Sie einen Platz wollen, dann würden Sie auch eine Variable für jede Diagonalrichtung haben müssen.

Natürlich, wenn das etwas komplizierter erscheint, als Sie möchten, würde ich ein Koordinatensystem empfehlen.

+0

Oh, das könnte es sein! Ich überprüfe jetzt, ob ich es schaffen kann! – Gurzo

+0

Ich habe das versucht, aber ich habe noch eine Frage. Was lege ich in den Erzeugungszyklus? Ich habe darüber nachgedacht, kann aber nicht den richtigen Code finden. Dann habe ich Methoden zum Setzen der angrenzenden Fliesen wie folgt gemacht: öffentlichen void setUp (Casella Fliese) { \t \t up = Kachel; \t \t tile.setDown (this); \t} So wird es die Verbindung zwischen beiden Kacheln auf einmal einstellen, ohne eine zu verpassen. Also, jede Hilfe mit dem Kartenerstellungszyklus? – Gurzo

+0

Wo immer Sie setUp aufrufen, müssen Sie auch die von Ihnen eingestellte Kachel in die ArrayList einfügen. Dann müssen Sie nur die erste Kachel in der ArrayList entfernen und die gleichen Operationen ausführen. – AlbertoPL

1

Der Code muss korrekt sein ist wirklich keine funktionale Anforderung, so ist es schwer zu sagen, was genau ist, ohne mehr über Ihr Spiel/Karte zu wissen. Wenn Sie eine Map mit X-Kacheln und keiner geordneten Adjazenz haben, ist eine nicht-matrikuläre Lösung die beste Lösung. Eine gängige Lösung besteht darin, sie einfach wie ein Diagramm zu modellieren, wobei entweder Adjazenzliste für nicht symmetrische Adjazenz oder Inzidenzliste für Symmetrie verwendet wird Nachbarschaft. Wenn Sie eine Inzidenzliste verwenden, benötigen Sie ein Edge-Objekt, das die Scheitelpunkte enthält, die die Edge verbindet, wenn Sie die Adjazenzliste verwenden, ist die Verwendung von multimap möglicherweise sehr angenehm.

Wenn Sie eine nicht-matrikuläre Lösung mit geordneter Umgebung wünschen, hat AlbertoPL die Lösung dafür.

Angenommen, Sie haben eine Karte, deren X-Kacheln breit und Y-Kacheln hoch sind und die nebeneinander liegenden Kacheln nebeneinander liegen, so dass jede Kachel maximal 4 und min 2 benachbarte Kacheln enthält, können Sie eine Matrix verwenden Kacheln und stellen auch Adjazenz durch Matrixadjazenz dar. Die Idee ist, dass map [Y] [X] benachbart zu Map [Y + 1] [X] und Map [Y] [X + 1] und umgekehrt ist. Diese Lösung könnte auch die Nachbarschaftsgrenzen von max. 6 und min 3 abdecken, wenn die Kachel [Y + 1] [X + 1] an die Kachel [Y] [X] angrenzt. Umgekehrt ist es, dass Sie die Karte leicht analysieren können, und da es 2 Dimensionen hat, ist es natürlich, es so zu modellieren. Nachteil ist, dass sobald eine Kachel gesetzt ist, Sie ihre Umgebung nicht ändern können, ohne die Matrix zu ändern. Da dies nicht das ist, was Sie Professor vorgeschlagen haben, möchten Sie es vielleicht nicht tun, aber wenn Sie (statische) geordnete Nachbarschaft haben, könnte dies der einfachste Weg sein, es zu tun.

+0

Die Anfangsidee war, eine Adjazenzliste zu verwenden. Im Moment versuche ich, Alberto so arbeiten zu lassen. Ich habe Ihre Methode übrigens verstanden, also danke!^_^ – Gurzo

2

Die Wände, Buggies und Bereiche sind spezielle Behälter, die alle Wände, Buggies und Bereiche des Spiels halten.

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

Dies ist das Niveau des Spiels. Außer dem Leerzeichen gibt es fünf Zeichen. Der Hash (#) steht für eine Wand. Der Dollar ($) repräsentiert die zu bewegende Box. Der Punkt (.) Steht für den Ort, an dem wir die Box verschieben müssen. Das at-Zeichen (@) ist der Sokoban. Und schließlich beginnt das neue Zeilenzeichen (\ n) eine neue Zeile der Welt.

+0

Als ich das erste Mal sah, habe ich über nPush (http://npush.sourceforge.net) –