Room
(Tom Krümmel)
Für einen Leveleditor, der Räume aneinandersetzen soll, ist es nahezu essenziell, eine Datenstruktur zu schaffen, die Räume darstellen kann. Hierfür haben wir die Klasse "Room" erstellt. Jene speichert Name, die Punkte mit kleinstem sowie größtem X/Y-Wert, seinen Mittelpunkt sowie eine Liste mitsamt aller seiner Türen (Ways). Außerdem verfügt "Room" über die Methoden "compareWays", "connect", "moveCenter", "rotate" und "paint". Außerdem erbt sie vom DrwableObject, um gezeichnet werden zu können. Die Funktionsweise der einzelnen Methoden werden im nachfolgenden Text erläutert.
compareWays
"compareWays" aktualisiert die Liste aller noch offenen Türen des momentanen Levels. Dies ist nötig, da die Türen, die nicht als Verbindung zwischen Räumen dienen, das Ende des Levels darstellen. Desweiteren ruft sie die Methode "connect" auf, um einen weiteren Raum mit dem aktuellen zu verbinden, falls der User ihn nah genug an den aktuellen platziert hat. Deshalb ist compareWays vom Typ boolean, da es true zurückgibt, wenn dies gelingt.
Die Methode beginnt, indem neue LinkedLists mit dem Inhalt aller Türen sowie der des aktuellen Raums erstellt werden und führt den boolean added ein.
boolean added = false;
LinkedList<Way> cutways = new LinkedList<>(allways);
LinkedList<Way> ownways = new LinkedList<>(waylist);
Anschließend wird in einer doppelten for-Schleife jede Tür des aktuellen Raums mit jedem offenenen Raum verglichen, indem die "compareDistance" Methode der Raumtür mit der aktuellen Leveltür als Input auf. Gibt diese true zurück, signalisiert also die Möglichkeit der Verbindung, wird diese Tür aus beiden Listen entfernt.
if (roomway.compareDistance(mapway)) {
ownways.remove(roomway);
cutways.remove(mapway);
}
Danach wird der aktuelle Raum, falls dies noch nicht geschehen ist, mit dem des Weges zugehörigen Raum verbunden. Außerdem wird die Tür, anhand derer verbunden wurde, aus der Liste der noch offenen Türen des Vaters gelöscht und der Liste der noch offenen Türen die aktuelle Liste des Raumes hinzugefügt, ohne den verbundenen Weg.
if (!added) {
connect(roomway, mapway);
cutways.addAll(ownways);
}
mapway.getFather().getWaylist().remove(mapway);
added = true;
Zum Ende der Methode wird noch die alte Liste der noch offenen Türen sowohl des Raumes als auch des Levels mit den veränderten überschrieben und added wird zurückgegeben.
allways.clear();
allways.addAll(cutways);
return added;
Connect
Die Connectmethode hat das Ziel, die Koordinaten des aktuellen Raumes an den eines anderen anzupassen, sodass sie eine übereinstimmende Schnittstelle haben, sowohl skaliert dargestellt als auch in den in der XML gespeicherten Doubles. Hierfür bekommt sie eine Tür des aktuellen Raumes sowohl eine eines anderen Raumes als Input, die vorher schon auf Verbindbarkeit geprüft wurden. Wichtig hierbei ist, dass der aktuelle Raum derjenige ist, den der Benutzer anhand der Maus frei bewegt.
Die Connectmethode beginnt, indem sie die skalierten Intkoordinaten des Centers des aktuellen Raumes, sowie derer der beiden Türen mithilfe der Koordinatenklasse berechnet.
Point thisCenter = ownway.getFather().getCenter().getScaledIntCoordinates(ownway.getFather().getCenter());
Point otherDoor = otherway.getPos().getScaledIntCoordinates(otherway.getFather().getCenter());
Point thisDoor = ownway.getPos().getScaledIntCoordinates(ownway.getFather().getCenter());
Im Anschluss werden die Koordinaten der Schnittstelle berechnet, indem der Abstand der aktuellen Tür zum Centerpunkt auf die X und Y Koordinate der anderen Tür addiert wird. Außerdem wird aus diesen eine neue Koordinate erstellt inklusive aktueller Drehung.
int newPosX = otherDoor.x + (-thisDoor.x + thisCenter.x);
int newPosY = otherDoor.y + (-thisDoor.y + thisCenter.y);
Coordinates paintPosition = new Coordinates(newPosX, newPosY);
paintPosition.setAngle(ownway.getFather().getCenter().getAngle());
Desweiteren werden zwei neue Koordinaten erstellt aus den beiden Koordinaten der Türen. Diese werden mithilfe von for-Schleifen noch richtig rotiert.
Coordinates ownpos = new Coordinates(ownway.getPos());
Coordinates otherpos = new Coordinates(otherway.getPos());
for (int i = 0; i < ownway.getFather().getCenter().getAngle(); i += 90) {
ownpos = ownpos.rotation(90, ownway.getFather().getCenter(), ownpos);
}
if(otherway.getFather().getCenter().getAngle()>0){
for (int i = 0; i < otherway.getFather().getCenter().getAngle(); i += 90) {
otherpos = otherpos.rotation(90, otherway.getFather().getCenter(), otherpos);
}
}
Anschließend werden X und Y Koordinate der anderen Tür auf das Center seines Raumes addiert und für den aktuellen Raum die X und Y Koordinate der Tüposition von den korrespondierenden Centerwerten subtrahiert, um die Distanz der Center zu erhalten.
double dx1 = otherpos.getX()+otherway.getFather().getCenter().getX() ;
double dx2 = ownway.getFather().getCenter().getX() - ownpos.getX();
double dy1 = otherpos.getY()+otherway.getFather().getCenter().getY() ;
double dy2 = ownway.getFather().getCenter().getY() - ownpos.getY();
Falls der aktuelle Raum gedreht wurde, werden dx1 und dy1 mit der des anderen raumes getauscht, um akkurat zu bleiben.
if(ownway.getFather().getCenter().getAngle()==90){
dx1 = otherpos.getX()+otherway.getFather().getCenter().getY() ;
dy1 = ownpos.getY()+otherway.getFather().getCenter().getX() ;
}
Dem folgend wird aus der Distanz das neue Center berechnet und das Center des aktuellen Raumes zum Zeichnen um PainPosition bewegt und das mit Doubles arbeitende Center gesetzt.
this.cC = new Coordinates(dx1 + dx2, dy1 + dy2);
moveCenter(paintPosition, ownway.getFather().getCenter().getAngle());
ownway.getFather().cC=new Coordinates(this.cC);
moveCenter
Die moveCenter methode bewegt das aktuelle Center zu einer als Input gegebenen Koordinate (Coordinates oder Punkt, die Funktionsweise ist identisch) und dreht sämtliche Koordinaten des Raumes um einen angegebenen Winkel.
Zunächst wird das aktuelle Center mit dem neuen Center überschrieben.
this.cC.setPosy(newC.getPosy());
this.cC.setAngle(newC.getAngle());
Dann werden die Eckpunkte des Raumes und alle dem Raum anhängenden Türen um die die Differenz zum neuen Center verschoben.
this.cE.setPos(newC.addCoordinats(cE.getVector()));
for (int i = 0; i < waylist.size(); i++) {
waylist.get(i).getPos().setPos(newC.addCoordinats(waylist.get(i).getPos().getVector()));
}
Dasselbe gilt für die Rotation.
for (int i = 0; i < newC.getAngle(); i += 90) {
this.cA.rotation(90, newC);
this.cE.rotation(90, newC);
for (int j = 0; j < waylist.size(); j++) {
waylist.get(j).getPos().rotation(90, cC);
}
}
Rotate
Die Rotatemethode rotiert alle Koordinaten des Raumes. Rotate ruft die Rotationsmethode der Koordinaten für alle Koordinate des Raumes sowie der Position der Türen mit dem Winkel 90 Grad auf. Dies haben wir so implementiert, da der Endnutzer sowieso nur um 90,180 oder 270 Grad drehen möchte.
Paint
Wie der Name schon sagt, zeichnet die Paintmethode den Raum. Die Paintmethode ho lt sich zunächst die skalierten Intkoordinaten des Mittelpunktes und zeichnet diesen. Anschließend tut sie dasselbe mit den beiden Eckpunkten und zeichnet dann zwischen dem größten X Wert und dem kleinsten X/Y Wert, dem kleinsten Y Wert und dem größten/kleinsten Y Wert etc. Linien. Dabei wird die Farbe auf schwarz gesetzt. Außerdem zeichnet sie alle Wege.
g.setColor(Color.BLACK);
// center anzeigen
Point middle = cC.getScaledIntCoordinates(cC);// new Point();
middle.paint(g);
Point a = cA.getScaledIntCoordinates(cC);
Point e = cE.getScaledIntCoordinates(cC);
// rechteck zeichnen
Point ur = new Point(e.x, a.y);
Point ll = new Point(a.x, e.y);
new Line(a, ur).paint(g);
new Line(ur, e).paint(g);
new Line(e, ll).paint(g);
new Line(ll, a).paint(g);
// wege zeichnen
for (Way roomway : waylist) {
roomway.paint(g);
}