Iteration über isometrische Map

Tiim

Mitglied
Hallo zusammen

Ich bin gerade dabei, einen Mapeditor für ein isometrisches Spiel zu schreiben. Dazu muss ich Items, die auf der Karte sind, von hinten nach vorne Rendern.

Dazu muss ich über die Map, welche ich wie einen 2D Array benutzen kann, folgender massen iterieren:
attachment.php


Irgendwie komm ich da nicht weiter.. diesen Code, den ich vor Ewigkeiten geschrieben habe, iteriert nur genau über die hälfte der Map, und ich habe keinen Plan mehr, was der tut:

Java:
//w = MapBreite
//h = MapHöhe
for (int x = w - 1; x >= 0; --x) {
    for (int y = 0, x2 = x; (x2 <= (w - 1)) && (y < h); ++y, ++x2) {

        render(x2,y);

    }
}

Ich wäre froh, wenn ihr mir helfen könnt, oder mir sagt, was ich falsch gemacht habe.
 

Anhänge

  • iso.jpg
    iso.jpg
    41,3 KB · Aufrufe: 52
Hab mich auch mal damit beschäftigt. Was mir sehr geholfen hat war das hier

Ein richtig gutes Isometric Tutorial, zwar in C# fürs XNA Framework, aber ist ja alles analog übertragbar

Schau dir alle Teile davon an (sind glaub ich 8 Stück)

das wird dir definitiv helfen!

XNA Resources
XNA Resources
Grüße
 
Alternativ hier mal auf die Schnelle:

Java:
public class IsometricTiles {
	
	private static class Tile{
		String value = "xxx";
	}
	
	public static void main(String[] args) {
		Tile[][] map = new Tile[5][19];
		//initialise map
		for (int h = 0; h < map[0].length; h++) {
			for (int w = 0; w < map.length; w++) {
				map[w][h] = new Tile();
			}
		}
		//counter for iterations, not needed for logic
		int counter = 1;
		
		//actual H-Position
		int actualH = 0;
		//the start-w-position of the current diagonal iteration
		int iterationStartW = map.length - 1;
		//actual W-Position
		int actualW = iterationStartW;
		//iterate diagonal until iterations can reach the nearest tile
		while (iterationStartW > -map[actualW].length && actualH < map[actualW].length) {
			visit(map[actualW][actualH],counter++);
			//iterate diagonal
			actualH++;
			actualW++;
			//iteration will end at max W or at max H
			if (actualW >= map.length || actualH >= map[actualW-1].length) {
				//start at the next lower W position
				actualW = --iterationStartW;
				if (actualW < 0) {
					//in case of the lower-left half start at left side and lower
					actualH = -actualW;
					actualW = 0;
				} else {
					//otherwise start at h = 0
					actualH = 0;
				}
			}

		}

		//print tiles
		for (int h = 0; h < map[0].length; h++) {
			for (int w = 0; w < map.length; w++) {
				System.out.print(map[w][h].value + " ");
			}
			System.out.println();
		}
	}

	private static void visit(Tile tile, int counter) {
		String value = String.valueOf(counter);
		while(value.length() < 3){
			value = "0"+value;
		}
		tile.value = value;
	}

}

Die Idee davon ist eigentlich nur, das ich ein durchgehendes Iterationsmuster beibehalte (immer ein Feld weiter nach rechts und eins nach unten). Erreiche ich einen Rand setze ich meine Felder zurück. In welcher Iteration ich bin merke ich mir an der aktuellen w-koordinate.
Um die untere linke Hälfte zu erreichen (w==0 würde nur für bis zur mitteldiagonalen reichen), iteriere ich solange bis ich auch die untere ecke erreiche (und die ist abhängig von der höhe - aus dem grund taucht zweimal die höhe in der schleifenbedingung auf).
Für die untere hälfte starte ich dann entsprechend nicht in zeile 0 und am iterations-W sondern in der Zeile bei der ich gerade mit der iteration bin und spalte 0.
[EDIT]Die Ausgabe entspricht deiner Tilemap um 45 Grad nach Rechts gekippt.
Für 4x7
Code:
007 004 002 001 
011 008 005 003 
015 012 009 006 
019 016 013 010 
023 020 017 014 
026 024 021 018 
028 027 025 022

Für 6x3
Code:
013 010 007 004 002 001 
016 014 011 008 005 003 
018 017 015 012 009 006

Für 5x5
Code:
011 007 004 002 001 
016 012 008 005 003 
020 017 013 009 006 
023 021 018 014 010 
025 024 022 019 015
[/EDIT]


Gruß
 
Vielen vielen Dank euch. Ich hätte nicht erwartet, dass das so schnell geht 😀

@Helgon
Die XNA referenzen werde ich bestimmt noch ein paar mal anschauen, wenn ich Probleme mit dem Editor bekomme.

@Firephoenix
Dein Beispiel "auf die Schnelle" funktioniert perfekt.

Nochmals vielen Dank :toll:

Gruss Tiim
 

Zurück
Oben