Realistische Schatten für Roguelike

Bild

Gute Zeit, Habr Gemeinschaft.

Vor vielen Jahren bin ich auf einen Beitrag gestoßen (1) . Dann war ich verwirrt über die Möglichkeit, interessante Elemente für das Gameplay in Roguelike (2) zu erstellen. Angenommen, ein Gegner kann sich hinter einer Mauer befinden. Wir sehen ihn erst, wenn wir ihn in Sichtweite treffen. Aber ich bevorzuge die Situation, in der wir, wenn wir durch die Korridore des Verlieses reisen, die Merkmale der Position von Objekten nach und nach anhand des Sichtbereichs aufdecken.

Später in den Beiträgen: (3) , (4) und (5) wurden die Fragen des Schattenwerfens in 2D-Spielen behandelt. Wie sowohl von den Autoren selbst als auch in den Kommentaren festgestellt, ist die Berechnung von Schatten ziemlich umfangreich und keine leichte Aufgabe, sowohl für den Taschenrechner als auch für das Design.

Irgendwie hatte ich einige freie Tage und beschloss, auf die Frage nach vielversprechenderen Schatten zurückzukommen. Es ist klar, dass die Grafikkarte erfolgreich und schnell mit Schatten umgeht, aber in diesem Fall wollte ich die Schatten für ein 2D-Spiel verarbeiten, und es schien überflüssig, Berechnungen auf die Grafikkarte zu übertragen. Ja, und die Prozessorleistung ist in den letzten Jahren insgesamt gewachsen, eigentlich ein Beitrag darüber, was am Ende passiert ist.

Das Programm wurde in Pascal geschrieben, einfach weil ich es gut kenne, und Lazarus ist eine offene IDE mit einer Vielzahl von Komponenten.

Die ursprüngliche Idee war, vom Betrachter Linien durch jede der Ecken der Kachel zu ziehen und dann die resultierende Figur abzudunkeln.

Bild

Ein solcher Schatten sieht jedoch etwas unnatürlich aus, wenn sich der Blickwinkel ändert. Die Schatten sind jetzt breiter, jetzt schmaler.

Bild

Der Schatten eines runden Objekts sieht viel besser aus. Um einen solchen Schatten zu erzeugen, müssen Sie zwei Tangenten vom Beobachtungspunkt zum Kreis und zu den Rändern des Bildschirms zeichnen. Der Durchmesser des Kreises entspricht der Größe der Fliese.

In meinem Programm habe ich folgende Funktion verwendet:

//       function tangent_to_circle(x1,y1,x2,y2,r:Single; var x3,y3,x4,y4:Single):Boolean; var l,dx,dy,i,ii,ij:Single; begin dx := x1 - x2; dy := y1 - y2; l := Sqrt(dx*dx + dy*dy); if l<=r then begin tangent_to_circle:=false; exit; end; i := r/l; ii := i*i; ij := i * Sqrt(1 - ii); x3 := x2 + dx*ii - dy*ij; y3 := y2 + dx*ij + dy*ii; x4 := x2 + dx*ii + dy*ij; y4 := y2 - dx*ij + dy*ii; tangent_to_circle:=true; end; 

Wobei (x1, y1) der Beobachtungspunkt ist, (x2, y2) der Mittelpunkt des Kreises ist, ® sein Radius ist und (x3, y3) und (x4, y4) die Schnittpunkte der Linien und des Kreises sind. Die Funktion gibt nur dann true zurück, wenn sich der Beobachter außerhalb des Kreises befindet.

Da der Prozessor nicht sehr trigonometrisch ist, habe ich versucht, ihn auf ein Minimum zu beschränken. Experten, die sich auf eine einfache Regel (grobes Modell) stützen, werden Ihnen sagen, warum.

(Schlecht) SIN, COS ..> '/', SQRT> 'DIV', 'MOD'> 'SHR', 'SHL'> '*'> ': =', '+', '-', 'AND ',' XOR '.. (Gut)

Es ist eine Freude, den grafischen Teil von Grundelementen auf der Leinwand zu implementieren. Es gibt viele Bibliotheken und Engines, die die Arbeit erleichtern. Bei der Entwicklung auf Delphi musste ich die Agg2D-Bibliothek verwenden, auf Lazarus gibt es ihren Port (6) , und darauf habe ich beschlossen, die Idee zu verwirklichen. Tatsächlich besteht der Vorteil der Bibliothek darin, dass den RGB-Farben ein Alphakanal hinzugefügt wird und die Grundelemente geglättet werden. Aufgrund des direkten Zugriffs auf Pixel und verschiedener Tricks ist die Verarbeitung viel schneller als die Leinwand.

Beim Zeichnen des Schattens der Kachel wollte ich den Sektor ursprünglich mit Schatten füllen, aber dann war das Bild innerhalb der Kachel schlecht unterscheidbar (der betreffende Sektor in Abbildung 3 ist mit Grün gefüllt). Nachdem ich mit verschiedenen Optionen experimentiert hatte, hörte ich auf, einen Sektor aus dem Schattenbereich auszuwählen.

Um den Sektor zu zeichnen, benötigen wir einen Winkel im Bogenmaß, aber die Trigonometrie konnte dies immer noch nicht. (arctan2 - Funktion der Mathematikmodulbibliothek)

 //     function alpha_angle(x1,y1,x2,y2:Single):Single; begin alpha_angle := arctan2(y1 - y2, x1 - x2); end; 

Eigentlich ist alles bereit für die Bildmontage. Wir nehmen eine Karte mit Kacheln und wenden nacheinander nacheinander Schatten an. Bei Bäumen sind die Schatten dunkler, bei anderen Objekten sind die Schatten transparenter.

Bild

Das fertige Bild wird auf die Hauptschicht der Kacheln angewendet. Ein bisschen Hintergrunddesign und allgemeinere Kachelsätze. Eigentlich habe ich zwei Tage gebraucht, um nach geeigneten Kachelsätzen zu suchen, die gemeinfrei oder von sehr geringer Qualität sind oder Geld kosten. Infolgedessen zeichnete er die Bäume selbst und lieh sich andere Elemente vom Benutzer Joe Williamson (7) (ausgezeichneter Stil).

Bild

Das wäre alles vorbei, aber die Leistung war etwas sedimentär. Mit der Anzahl der Objekte beginnt ungefähr fünfhundert Drawdown. Verschiedene Optimierungsmethoden wurden in Betracht gezogen, und die Aufteilung in Kernel und die Beschränkung des Zeichenbereichs auf einen bestimmten Radius, die Änderung der Form des Schattens (auf einen günstigeren Wert als Bögen). Ich dachte sogar daran, die Berechnung auf Video zu übertragen.

Infolgedessen kam ich zu dem Schluss, dass die beste Option darin besteht, die Abtastung des als Schattenmaske dienenden Bildes zu reduzieren. Da die Anzahl der Berechnungen erheblich reduziert wird, sowie der unerwartete Effekt der Pixelung der Schattenkonturen, was einen gewissen Charme der alten Schule verleiht.

Bild

Der Effekt hat mir so gut gefallen, dass ich die Skalierung durch einen bestimmten Multiplizitätsparameter zu einem dynamischen Prozess machen musste.

Bild

Alles, was blieb, war, undurchsichtige Wände zu schaffen und das Ergebnis der Gemeinde zu präsentieren.

Bild

Ich freue mich auf neue Spiele mit diesem Effekt oder seiner Entwicklung.
Vielen Dank!

Demo, in der Sie die Griffe berühren können (exe für Windows).

Teil 2 , Teil 3

Referenzen:
1) habr.com/post/16927/
2) en.wikipedia.org/wiki/Roguelike
3) habr.com/post/204782/
4) habr.com/post/305252/
5) habr.com/post/319530/
6) wiki.freepascal.org/BGRABitmap
7) twitter.com/joecreates

Source: https://habr.com/ru/post/de430438/


All Articles