isometrische Zeichenreihenfolge mit Bildern, die größer als einzelne Kacheln sind - Zeichnungsreihenfolge-Algorithmus?

8

Ich habe eine isometrische Karte, über die ich verschiedene Bilder lege. Die meisten Bilder passen über eine einzelne Kachel, einige Bilder sind jedoch etwas größer. Zum Beispiel habe ich ein Bett mit Fliesen der Größe 2x3.

Dies führt zu einem Problem beim Zeichnen meiner Objekte auf dem Bildschirm, da einige Kacheln fälschlicherweise andere Kacheln überlappen.

Die beiden mir bekannten Lösungen bestehen darin, das Bild entweder in 1x1-Kachelsegmente aufzuteilen oder meinen eigenen Algorithmus für die Zeichenreihenfolge zu implementieren, indem beispielsweise jedem Bild eine Nummer zugewiesen wird. Das Bild mit der Nummer 1 wird zuerst gezeichnet, dann 2, 3 usw.

Hat jemand einen Rat, was ich tun soll?

Mir scheint, dass das Aufteilen eines isometrischen Bildes nicht offensichtlich ist. Wie entscheiden Sie, welche Teile des Bildes sich in einer bestimmten Kachel befinden? Ich kann es mir auch nicht leisten, alle meine Bilder manuell aufzuteilen.

Der Zeichnungsreihenfolge-Algorithmus scheint eine bessere Wahl zu sein, aber ich bin mir nicht sicher, ob er einfach zu implementieren sein wird. Ich kann in meinem Kopf nicht lösen, wie ich mit Situationen umgehen soll, in denen Sie den Index eines Bildes ändern, wodurch viele andere Bilder beeinträchtigt werden. Wenn jemand Ressourcen / Tutorials dazu hat, wäre ich sehr dankbar.

Roger Smith
quelle

Antworten:

3

Was Sie brauchen, nennt man einen Malalgorithmus.

Sie möchten zuerst das am weitesten entfernte Plättchen zeichnen, einschließlich aller Doodads oder Charaktere darauf.

Zeichnen Sie dann den nächstgelegenen und wiederholen Sie den Vorgang, bis Sie fertig sind.

Für Ihre Objekte, die mehr als eine Kachel umfassen, muss ein Anker- / Ursprungspunkt deklariert sein. Dies ist die Gitterzelle, die beim Zeichnen dazu führt, dass auch Ihr größeres Objekt gezeichnet wird. Der Ursprungspunkt wird so gewählt, dass er gezeichnet wird, nachdem alle Zellen, in die das Objekt blutet, zuerst gezeichnet wurden.

Basierend auf Ihrer Frage ist Ihr Ursprungspunkt die Kachel, die der Kamera am nächsten liegt. (Wenn Sie quadratische statt rautenförmige Kacheln verwenden, sollten Sie entweder die Kachel unten links oder unten rechts auswählen.)

Beispielcode für ein quadratisches Gitter. Ändern Sie die Schleifenrichtung für Ihr Diamantgitter.

for(int y = 0; y < GridHeight; ++y) {
    for(int x = GridWidth - 1; x > -1; --x) {
        MapCell cell = getMapCell(x,y);
        DrawTerrain(cell);
        if(cell.IsDoodadOrigin){
            DrawDoodad(cell);
        }
        if(cell.IsCharacterOrigin){
            DrawCharacter(cell);
        }
    }
}
Jim
quelle
Ich sehe nicht, wie das funktionieren kann? Stellen Sie sich ein 2x3 Bett vor, das vollständig von Kisten umgeben ist. Wenn Sie durch die Zellen iterieren, haben Sie bis zum Erreichen des „Ursprungs“ des größeren Objekts bereits Kästchen gezeichnet, die sich hinter und vor dem Bett befinden sollten.
Wozza
Sie haben Recht, diese Technik funktioniert für quadratische Gitter. Es funktioniert auch für diagonale Gitter, die quadratische Doodads / Zeichen verwenden. Es funktioniert nicht für die unregelmäßige 2x3-Form in einem diagonalen Raster.
Jim
3

Teilen Sie Ihre Objekte in 1 × 1 × 1-Würfel und weisen Sie jedem Würfel ein Bild der Teile des Objekts zu, die sich physisch in diesem Würfel befinden würden.

Dies ist einfach, wenn Sie mit tatsächlichen 3D-Objekten beginnen und diese in 2D rendern. Wenn Sie Ihre Objekte direkt in 2D zeichnen (oder wenn Sie bereits Kunstwerke haben, die Sie teilen müssen), ist ein manueller Aufwand erforderlich. Glücklicherweise muss die Aufteilung nicht genau sein, solange Sie sicherstellen, dass keiner der einem bestimmten Würfel zugewiesenen Bildteile außerhalb des sechseckigen Bereichs verschüttet wird, den ein fester 1 × 1 × 1-Würfel an dieser Position abdecken würde. Es kann hilfreich sein, eine Überlagerung zu erstellen, in der die Umrisse jedes Würfels als zusätzliche Ebene in Ihrem Grafikeditor angezeigt werden.

Dann weisen Sie jedem Würfel einfach eine Priorität als p = x + y + z zu (vorausgesetzt, alle drei Koordinaten nehmen zur Kamera hin zu) und rendern die Würfel in aufsteigender Reihenfolge nach Priorität.


Hier ist ein kurzes Beispiel basierend auf diesem Bild aus Wikimedia Commons (von Phasmatinox / Allefant , verwendet unter der CC-By-SA 3.0- Lizenz):

        Isometrische Projektion eines erweiterten Objekts, das in Würfel unterteilt ist

Die Kommode auf dem Bild nimmt zwei Kacheln ein, und ich habe die Grenzen dieser Kacheln (die roten Sechsecke) darüber gezeichnet. Die Teile des Bildes, die in jedem Sechseck liegen, sollten der entsprechenden Kachel zugewiesen werden. Der Teil, in dem sich die Sechsecke überlappen, kann entweder einer Kachel (oder sogar beiden, wenn Sie möchten) zugewiesen werden, da die Auswahl das Endergebnis nicht beeinflusst.

Beachten Sie, dass Sie diesen einfachen Algorithmus möglicherweise näher erläutern müssen, wenn sich mehrere Objekte in einer Kachel, Wände / Böden zwischen Kacheln oder Objekte (z. B. Personen) reibungslos zwischen Kacheln bewegen können. Wände und Böden sind recht einfach zu handhaben: Sie können an jedem Punkt nach dem Inhalt der Kachel, vor der sie sich befinden (aus Sicht der Kamera) und vor der Kachel, hinter der sie sich befinden, gezeichnet werden. Dies ist auch eine nützliche Faustregel für Objekte, die sich zwischen Kacheln bewegen. Behandle sie wie eine Wand zwischen diesen Fliesen.

Bei mehreren Objekten in einer Kachel sind diese manchmal recht einfach: Wenn Sie beispielsweise ein Buch auf der Brust im Bild hatten, sollte es offensichtlich nach der Oberfläche gezeichnet werden, auf der es liegt. Es kann jedoch komplizierter werden, wenn Sie beispielsweise Objekte haben, auf denen Menschen sitzen können. Wenn beispielsweise eine Person auf einer Bank saß und von der Kamera abgewandt war, sollte der Körper der Person nach der Bank gezogen werden, aber ihre Beine (die sich hinter der Bank von der Kamera befinden) müssen davor gezogen werden. Eine Lösung wäre in diesem Fall, die Beine einer sitzenden Person in eine separate Komponente mit eigener Position zu teilen (entweder in der angrenzenden Kachel oder zwischen den Kacheln).

Ilmari Karonen
quelle
1

Es kann Ihnen helfen, Ihre Objekte nach Typ oder Höhe zu unterteilen. Zum Beispiel sollte Landschaft (Böden, Wände) vor Objekten (Betten) gezeichnet werden. Aufgrund der isometrischen Perspektive sollten Kacheln mit geringerer Höhe vor Kacheln mit höherer Höhe gezeichnet werden.

Wenn Sie sich für die Indexnummerierung entscheiden (eigentlich Z-Reihenfolge), empfehle ich, Lücken zwischen den Nummern zu verwenden - machen Sie nicht Ihre Böden 1und Ihr Bett 2. Verwenden Sie etwas wie Fußböden = 10und Betten = 20oder 100oder etwas anderes, damit Sie Dinge in die Mitte "einfügen" können, ohne alles andere zu dominieren.

Asche999
quelle
Ich habe vor, das zu tun, was Sie im ersten Absatz vorschlagen. Das Problem, das ich habe, ist, dass sich die Objekte eines ähnlichen Typs falsch überlappen. zB überlappt mein Bett den Nachttisch. Ich habe vorgeschlagen, dass ich jeder Instanz eines Bildes eine andere Nummer gebe, zum Beispiel nicht allen Betten die Nummer 20?
Roger Smith
Es hängt davon ab, ob. Was ist, wenn Sie zwei Betten nebeneinander haben? Eine Möglichkeit, dies häufig zu umgehen, besteht darin , Objekte in der Reihenfolge hinzuzufügen, in der sie gezeichnet werden sollen, aber ich weiß nicht, ob dies Ihnen helfen wird.
Asche999
1
Wenn zwei Betten nebeneinander liegen, sollte das Bett mit dem höheren y-Wert übereinander gezogen werden. Wenn sie die gleiche y-Koordinate haben, dann die mit dem höchsten x-Wert (vorausgesetzt, der obere Rand der Karte ist (0,0).
Roger Smith