Liebes Tagebuch ...
Ich habe vor kurzem den
SortStructuredList()-Befehl kennen und lieben gelernt.
Bei meinem Projekt mußte ich mich sehr früh mit der Frage auseinandersetzen, wie ich das regele, wenn sich zwei actors() auf ein und demselben Tile befinden. Zum Beispiel kann sich dort ein Pattern-actor() befinden (üblicherweise Blutspritzer), ein Item, und ein Monster. Damit ich in der draw()-Routine nicht jedesmal umständlich abfragen muß, welcher actor() Priorität beim Zeichnen hat, lasse ich dieses die Listenelemente einfach unter sich selbst regeln ...
Dafür habe ich jedem Element ein Atribut namens actor()\depth gegeben. Dahinter verbirgt sich die Information, in welcher Zeichentiefe sich ein Actor befindet.
Folgende "Tiefen" habe ich initialisiert:
Code: Alles auswählen
#maxDepth = 4
Enumeration
#patternDepth
#aboveDepth
#itemDepth
#npcDepth
#playerDepth
EndEnumeration
In der sehr frühen "GameJam"-Version des Spiels habe ich mir eine schmutzige, aber ausreichend effiziente draw-Order aus den Knöcheln gekloppt ... die Lösung war nicht besonders elegant, aber funktionierte. Und bei der geringen Menge an Witzgrafiken fiel der wiederholte Schleifendurchlauf nicht weiter ins Gewicht:
Code: Alles auswählen
For a = 0 To #maxDepth
ForEach actor()
If actor()\depth = a
//drawActorSprite
EndIf
Next
Next
Und dann habe ich SortStructuredList() entdeckt ...
Ab sofort muß jede Routine, welche einen actor() erschaffen will, dieses über einen Aufruf der Prozedur
spawnActor() erledigen.
Hier ist die Actor-Fabrik! Nur hier dürfen neue Listenelemente erschaffen werden!
Der Prozedur werden die wesentlichen Parameter (Typ/Subtype/Location/Status/Index) mitgeteilt, ein default-Actor wird erschaffen, welcher anschließend in einer
Select/Endselect-Routine für seine spezifische Aufgabe "spezialisiert" wird, und am Schluß mit den übergebenen individuellen Parametern "Charakter" bekommt.
Und ganz am Ende genügt ein simples
Code: Alles auswählen
SortStructuredList(actor(),#PB_Sort_Ascending,OffsetOf(ACTOR\depth),TypeOf(ACTOR\depth))
und ich kann in der draw()-Routine mittels einer simplen
ForEach ... Next-Schleife alle actor()-Elemente auf einmal in der richtigen Reihenfolge zeichnen!
Wenn ein actor() gelöscht wird, habe ich dafür eine eigene
killActor()-Routine eingerichtet, welche alle übrigen Aufgaben erledigt, die dabei anfallen: die Liste muß nicht neu sortiert werden, aber zum Beispiel müssen Kollision upgedated, und diverse fieldMatrix-Arrays, welche ich für schnelle Zwischendurch-Abfragen eingerichtet habe, aktualisiert werden. So habe ich die wesentlichen Aufgaben für meine Logik in zwei seperaten Prozeduren zentralisiert, und wenn mal etwas schief läuft, weiß ich sofort, wo ich gucken muß.
Da beim Speichern und Neuladen die Liste in der aktuellen Reihenfolge abgelegt, und auch so wieder hergestellt wird, entfällt ein neues Sortieren beim Laden eines Speicherstandes.
diceman hat geschrieben:
Derren hat geschrieben:Ich habe noch nie so ein Spiel (roguelike) gespielt, von daher weiß ich nicht, ob das einfach so gehört, oder ob das der Sinn ist, aber wenn man schaufelt, muss man wohl mehr als einmal "gegen den Haufen rennen".
• Glaube mir, einmal gegen den Haufen rennen reicht ... es gibt einen kurzen Delay für den Schaufel-Sound, so ist es spannender, was man ausgräbt ... wenn du natürlich während dessen andauernd auf die Richtungstaste hämmerst, kann es durchaus passieren, daß du nach dem Ausgraben sofort ins "Loch fällst" und der Level beendet wird. Aber danke für das Feedback ... vielleicht wäre es besser, wenn man während dem Schaufeln einen Fortschrittsbalken angezeigt bekommt, damit sofort klar ist, was da gerade passiert.
Für diverse Aktionen im Spiel, welche einen kurzen Delay involvieren (meistens aus atmosphärischen Gründen, um z.B. einen Sound voll auszuspielen) habe ich thematische Progress-Bars implementiert, und das gefällt mir derzeit richtig gut.
Auch beim Buddeln gibt es jetzt einen solchen Fortschrittsbalken.
Also nochmal 1000 Dank fürs Feedback, Derren, ohne deinen Erfahrungsbericht wäre ich nicht auf das Problem aufmerksam geworden!