Ich habe Probleme mit isometrischen Wänden.
Ich zeichne isometrische Bodenfliesen mit der Back-to-Front-Rendering-Methode, und es funktioniert gut. Ich halte auch meine Bodenfliesen in einem schönen Raster richtig aufgereiht. Der Code (und dies scheint für die isometrische Bodenzeichnung ziemlich Standard zu sein) ist wie folgt:
%Vor%Das macht einen schönen kleinen Boden:
Das Gitter wird aus dieser Kachel konstruiert:
Leider, wenn ich die gleiche Logik für Wände benutze, geht alles bis zur Hölle.
%Vor%Ich benutze das als meine Wandfliese:
(es ist ein Platzhalter von Google Bildsuche, aber es sollte trotzdem funktionieren)
Das ist das Ergebnis, das ich bekomme:
Die Renderreihenfolge für meine Wände ist eindeutig korrekt, näher Wände rendern auf weiter entfernten Wänden, was ich will, aber die Positionierung ist auch schmerzhaft falsch, und ich weiß nicht genau, wie ich das korrigieren sollte Kurz vor der Verwendung von Pixelwerten.
Als Referenz habe ich einen Versuch mit hartkodierten Pixelwerten gemacht, weil ich festgestellt habe, dass von der rechten Ecke einer Wand zur rechten Ecke der nächsten Wand die Änderung genau (200, -100) Pixel war. Wenn ich meinen Rendering-Loop-Account dafür gemacht habe
%Vor%es hat gut geklappt, aber das ist keine brauchbare Lösung, weil es keine Vielseitigkeit erlaubt.
Also, auf der Suche nach Vorschlägen, wie ich meine isometrischen Wände ausrichten kann. Was mache ich falsch?
Danke!
Sie können nicht einfach denselben Zeichnungscode für Wände wie für Böden verwenden, da Wände und Böden nicht in derselben Ebene liegen: Böden sind flach (horizontal), während Wände vertikal sind. Sie müssen sie also etwas anders zeichnen.
Ihre x- und y-Koordinaten in der Bodenhülle bedeuten etwa "links / rechts" und "vorwärts / rückwärts" in Bezug auf die Platzierung der Fliesen. Für Ziegel sind links und rechts immer noch sinnvoll, aber wir wollen vorwärts / rückwärts durch nach oben und unten ersetzen, um die vertikale Richtung zu reflektieren. So bekommt unser "y" eine neue Bedeutung.
Nun, in Mathematik, zeigt die y-Achse normalerweise nach oben, während sie in 2D-Computergrafiken nach unten zeigt. Sie können wählen - der folgende Code geht davon aus, dass er nach oben zeigt, so dass y = 0
"auf der Bodenebene" bedeutet.
Lasst uns anfangen über Ordnung nachzudenken. Der Beispielziegel, den Sie gepostet haben, ist für eine Wand, die ein (oberes) linkes Ende eines Geschosses wäre. Wegen der schwarzen Teile des Ziegels (der Tiefe der Mauer) müssen wir sicherstellen, dass wir die Ziegel, die weiter vorne rechts liegen, so zeichnen, dass die schwarze Tiefe auf der linken Seite von engeren Ziegeln bedeckt wird. Das gleiche Argument gilt für das Schwarz am oberen Teil der Wand, wir müssen zuerst die unteren Ziegel zeichnen.
Wenn wir wie zuvor besprochen an der x- und y-Richtung bleiben (x geht von links nach rechts, y geht von unten nach oben), bedeutet dies, dass wir beide For-Schleifen in negative Richtungen laufen müssen:
%Vor%Die Hauptfrage ist jetzt, wie sehr wir die Zeichnung jedes Ziegels in Bezug auf die anderen Ziegel ausgleichen müssen. Lassen Sie uns die eine Richtung auf einmal machen, beginnend mit der x-Richtung.
Stellen wir uns nur zwei Steine nebeneinander vor:
Auf der linken Seite der beiden ist der schwarze Tiefenbereich sichtbar, aber der rechte sollte ihn nicht zeigen. Daher können wir das rechte Bild nicht einfach um die gesamte Breite des PNGs versetzen. In der Tat, vorausgesetzt, dass die Ziegel mit Ihren Bodenfliesen übereinstimmen, sollte die Breite des eigentlichen vorderen Teils der Wand gleich der halben Breite einer Fliese sein.
%Vor%Die schwarze Wandtiefe auf der linken Seite sollte nicht ignoriert werden, da wir wahrscheinlich jeden Stein ein wenig nach links versetzen wollen, so dass die x-Koordinate der vorderen Ecke der Wand nicht mit den Bodenfliesen übereinstimmt die X-Koordinate der hinteren Ecke.
Nun ist die y-Koordinate jedes Bricks etwas kniffliger, weil sie nicht nur von der gemauerten Reihe abhängt, sondern auch von der x-Koordinate: je weiter rechts, desto höher sollten wir zeichnen. Aber lassen Sie uns für einen Moment die x-Richtung ignorieren und versuchen, einfach eine Spalte von Steinen zu zeichnen:
Auch hier ist das Delta zwischen den y-Koordinaten der beiden Steine nicht die volle Höhe des PNG. Anders als im linken / rechten Fall, in dem wir angenommen haben, dass Steine mit Kacheln ausgerichtet sind, die es uns erlaubten, tileWidth
als das Delta-x zu verwenden, können Steine willkürliche Höhen haben. Aber wir können immer noch die tatsächliche Ziegelhöhe aus der Bildhöhe berechnen, weil wir wissen, dass die Tiefe auf der linken Seite und die Tiefe auf der Oberseite aufeinander ausgerichtet sein müssen.
Wenn wir uns das kleine transparente Dreieck in der oberen rechten Ecke des Ziegel-PNG ansehen, stellen wir fest, dass das Verhältnis seiner Breite und Höhe dasselbe wie das Verhältnis der Breite und Höhe einer Bodenplatte sein muss. Das erlaubt uns, einen yoffset aus dem oben berechneten xoffset zu berechnen und daraus die tatsächliche Höhe des Bricks abzuleiten:
%Vor% Beachten Sie, dass dies nur unter der Annahme funktioniert, dass am Rand des PNGs kein leerer Bereich vorhanden ist und dieser trotzdem aufgrund von Rundungsfehlern fehlschlagen kann. Sie können hier ggf. ein Math.ceil()
(oder einfach + 1
) hinzufügen.
Also für einfache Spalten, wir sollten jetzt gehen: wir können einfach unsere y
Variable mit der obigen wallHeight
multiplizieren. Aber wie bereits erwähnt, beeinflusst die x-Position eines Bricks auch die Y-Pixel-Koordinate. Wenn wir das erste Bild mit den zwei Steinen nebeneinander betrachten, wie viel mussten wir dann den rechten Stein aufstellen, um ihn mit dem linken Stein auszurichten? Nun, das hier ist wirklich einfach, denn es ist das gleiche wie mit Bodenfliesen: die halbe Höhe einer Fliese!
Also sind wir fertig. Wenn wir alles zusammenfügen, haben wir am Ende ein bisschen Code:
%Vor%(Ich gehe davon aus, dass wallWidth () und wallHeight () die Breite und Höhe des Baustein-PNGs zurückgeben.)
Beachten Sie, dass die drei Konstanten vor den for-Schleifen aus dem eigentlichen Zeichencode entfernt werden können - sie hängen nur von Bildeigenschaften und anderen Konstanten ab und müssen nicht jedes Mal neu berechnet werden, wenn wir die Wand zeichnen.
Wenn Sie sich die Bodenfliese ansehen, die wie ein Diamant geformt ist, indem Sie sie um eine halbe Breite und um eine halbe Länge nach oben bewegen, werden zwei Kanten ausgerichtet
Die Wandfliese ist keine Raute. Wenn Sie die halbe Breite und die halbe Länge verschieben, werden die Kanten, die Sie anpassen möchten, nicht ausgerichtet.
Gegeben u
= Abstand, um sich zu bewegen
und v
= Entfernung nach oben
und A
der isometrische Winkel
v = u*tan(A)
u
ist in diesem Fall die Breite der Vorderseite des Bildes.
Wenn die Fläche (das texturierte Bit) des Wandbildes mit der Kantenlänge der Bodenfliese übereinstimmt, ergibt dies
%Vor%In einem isometrischen Bereich gibt es drei Achsen, in die Sie hineinfahren können: Z für hoch und runter, X und Y für Ihre 'Diagonalen'.
Zuerst stellen wir uns die Pixel-Darstellung einer 1 Einheit mal 1 Einheit mal 1 Einheit isometrischem Würfel vor, wobei alle Seiten gleich lang dargestellt sind:
Es wäre A Pixel hoch auf der Z-Achse. Seine anderen Kanten wären auch A Pixel lang, aber um 60 Grad gedreht - also wäre es sin (30) * A Pixel hoch und cos (30) * A Pixel lang in X- und Y-Richtungen - aka, 0,5 * A und sqrt (3) / 2 * A.
Um also ein isometrisches würfelgroßes Objekt in X, Y und Z zu positionieren, müssen wir es auf dem Bildschirm x und y folgendermaßen übersetzen:
%Vor%Solange die von mir getroffenen Annahmen stimmen, sollte das funktionieren.
BEARBEITEN: Übrigens muss A hart codiert werden, wenn das Bild Tiefe hat und Sie daher A nicht automatisch aus den Bilddimensionen extrahieren können.