Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Game Art Effects

So erzeugen Sie schockierend gute 2D-Blitzeffekte

by
Difficulty:IntermediateLength:LongLanguages:

German (Deutsch) translation by Alex Grigorovich (you can also view the original English article)

Lightning hat in Spielen viele Verwendungsmöglichkeiten, von der Hintergrundatmosphäre während eines Sturms bis hin zu den verheerenden Blitzangriffen eines Zauberers. In diesem Tutorial erkläre ich, wie Sie programmgesteuert fantastische 2D-Blitzeffekte erzeugen: Schrauben, Zweige und sogar Text.

Hinweis: Obwohl dieses Tutorial mit C# und XNA geschrieben wurde, sollten Sie in der Lage sein, dieselben Techniken und Konzepte in fast jeder Spielentwicklungsumgebung zu verwenden.


Finale Videovorschau


Schritt 1: Zeichnen Sie eine leuchtende Linie

Der grundlegende Baustein, den wir zum Erstellen von Blitzen benötigen, ist ein Liniensegment. Öffnen Sie zunächst Ihre bevorzugte Bildbearbeitungssoftware und zeichnen Sie eine gerade Blitzlinie. So sieht meiner aus:

Line Segment

Wir möchten Linien unterschiedlicher Länge zeichnen, also schneiden wir das Liniensegment wie unten gezeigt in drei Teile. Dies ermöglicht es uns, das mittlere Segment auf jede gewünschte Länge zu dehnen. Da wir das mittlere Segment strecken werden, können wir es als nur ein einzelnes Pixel dick speichern. Da das linke und das rechte Stück Spiegelbilder voneinander sind, müssen wir nur eines davon speichern. Wir können es im Code umdrehen.

Divided Line Segment

Jetzt deklarieren wir eine neue Klasse für das Zeichnen von Liniensegmenten:

A und B sind die Endpunkte der Linie. Durch Skalieren und Drehen der Teile der Linie können wir eine Linie beliebiger Dicke, Länge und Ausrichtung zeichnen. Fügen Sie der Line-Klasse die folgende Draw()-Methode hinzu:

Hier sind Art.LightningSegment und Art.HalfCircle statische Texture2D-Variablen, die die Bilder der Teile des Liniensegments enthalten. ImageThickness wird auf die Stärke der Linie ohne das Leuchten eingestellt. In meinem Bild sind es 8 Pixel. Wir setzen den Ursprung der Kappe auf die rechte Seite und den Ursprung des mittleren Segments auf die linke Seite. Dadurch werden sie nahtlos zusammengefügt, wenn wir sie beide an Punkt A zeichnen. Das mittlere Segment wird auf die gewünschte Breite gestreckt und eine weitere Kappe wird an Punkt B um 180° gedreht gezeichnet.

Mit der SpriteBatch-Klasse von XNA können Sie in ihrem Konstruktor einen SpriteSortMode übergeben, der die Reihenfolge angibt, in der die Sprites gezeichnet werden sollen. Stellen Sie beim Zeichnen der Linie sicher, dass Sie einen SpriteBatch mit SpriteSortMode auf SpriteSortMode.Texture übergeben. Dies dient der Leistungssteigerung.

Grafikkarten sind großartig darin, die gleiche Textur viele Male zu zeichnen. Jedes Mal, wenn sie die Texturen wechseln, gibt es jedoch Overhead. Wenn wir eine Reihe von Linien ohne Sortierung zeichnen, zeichnen wir unsere Texturen in dieser Reihenfolge:

BlitzSegment, Halbkreis, Halbkreis, BlitzSegment, Halbkreis, Halbkreis, ...

Das bedeutet, dass wir die Texturen für jede gezeichnete Linie zweimal wechseln würden. SpriteSortMode.Texture weist SpriteBatch an, die Draw()-Aufrufe nach Textur zu sortieren, sodass alle LightningSegments zusammen gezeichnet werden und alle HalfCircles zusammen gezeichnet werden. Wenn wir diese Linien verwenden, um Blitze zu erstellen, möchten wir außerdem die additive Mischung verwenden, um das Licht aus überlappenden Blitzstücken zusammenzufügen.


Schritt 2: Gezackte Linien

Blitze neigen dazu, gezackte Linien zu bilden, daher benötigen wir einen Algorithmus, um diese zu generieren. Wir werden dies tun, indem wir zufällig Punkte entlang einer Linie auswählen und sie um einen zufälligen Abstand von der Linie verschieben. Die Verwendung einer völlig zufälligen Verschiebung führt dazu, dass die Linie zu gezackt wird, daher werden wir die Ergebnisse glätten, indem wir begrenzen, wie weit benachbarte Punkte voneinander verschoben werden können.

Making Jagged Lines

Die Linie wird geglättet, indem Punkte mit einem ähnlichen Versatz zum vorherigen Punkt platziert werden; Dadurch kann die Linie als Ganzes auf und ab wandern und gleichzeitig verhindern, dass ein Teil davon zu gezackt wird. Hier ist der Code:

Der Code sieht vielleicht etwas einschüchternd aus, ist aber nicht so schlimm, wenn Sie die Logik verstanden haben. Wir beginnen mit der Berechnung der Normalen- und Tangentenvektoren der Linie sowie der Länge. Dann wählen wir zufällig eine Reihe von Positionen entlang der Linie und speichern sie in unserer Positionsliste. Die Positionen werden zwischen 0 und 1 skaliert, sodass 0 den Anfang der Linie und 1 den Endpunkt darstellt. Diese Positionen werden dann sortiert, damit wir problemlos Liniensegmente zwischen ihnen hinzufügen können.

Die Schleife durchläuft die zufällig ausgewählten Punkte und verschiebt sie um einen zufälligen Betrag entlang der Normalen. Der Skalierungsfaktor ist dazu da, zu scharfe Winkel zu vermeiden, und die Hüllkurve stellt sicher, dass der Blitz tatsächlich zum Zielpunkt geht, indem sie die Verschiebung begrenzt, wenn wir uns dem Ende nähern.

Lightning BoltLightning BoltLightning Bolt

Schritt 3: Animation

Blitze sollten hell aufblitzen und dann ausblenden. Um dies zu handhaben, erstellen wir eine LightningBolt-Klasse.

Um dies zu verwenden, erstellen Sie einfach einen neuen LightningBolt und rufen Sie Update() und Draw() für jeden Frame auf. Der Aufruf von Update() lässt es verblassen. IsComplete zeigt Ihnen an, wenn der Bolzen vollständig ausgeblendet ist.

Sie können jetzt Ihre Bolzen zeichnen, indem Sie den folgenden Code in Ihrer Spielklasse verwenden:


Schritt 4: Branch Lightning

Sie können die LightningBolt-Klasse als Baustein verwenden, um interessantere Blitzeffekte zu erstellen. Sie können die Schrauben beispielsweise wie unten gezeigt verzweigen:

Brand Lightning

Um den Blitz zu verzweigen, wählen wir zufällige Punkte entlang des Blitzes und fügen neue Bolzen hinzu, die von diesen Punkten abzweigen. Im folgenden Code erstellen wir zwischen drei und sechs Zweige, die sich in einem Winkel von 30 ° vom Hauptbolzen trennen.


Schritt 5: Blitztext

Unten ist ein Video eines anderen Effekts, den Sie aus den Blitzen machen können:

Zuerst müssen wir die Pixel im Text ermitteln, den wir zeichnen möchten. Dazu zeichnen wir unseren Text auf ein RenderTarget2D und lesen die Pixeldaten mit RenderTarget2D.GetData<T>() zurück. Wenn Sie mehr über das Erstellen von Textpartikeleffekten erfahren möchten, habe ich hier ein ausführlicheres Tutorial.

Wir speichern die Koordinaten der Pixel im Text als List<Vector2>. Dann wählen wir in jedem Frame zufällig Paare dieser Punkte aus und erzeugen einen Blitz zwischen ihnen. Wir wollen es so gestalten, dass je näher zwei Punkte beieinander liegen, desto größer ist die Chance, dass wir einen Bolzen zwischen ihnen erzeugen. Es gibt eine einfache Technik, die wir verwenden können, um dies zu erreichen: Wir wählen den ersten Punkt nach dem Zufallsprinzip aus, und dann wählen wir eine feste Anzahl anderer Punkte nach dem Zufallsprinzip und wählen den nächsten.

Die Anzahl der getesteten Kandidatenpunkte beeinflusst das Aussehen des Blitztextes. Wenn wir eine größere Anzahl von Punkten überprüfen, können wir sehr nahe Punkte finden, zwischen denen Bolzen gezogen werden können, wodurch der Text sehr sauber und lesbar wird, jedoch mit weniger langen Blitzen zwischen den Buchstaben. Kleinere Zahlen lassen den Blitztext verrückter aussehen, aber weniger lesbar.


Schritt 6: Optimierung

Der Blitztext, wie oben gezeigt, kann reibungslos laufen, wenn Sie einen Computer der Spitzenklasse haben, aber es ist sicherlich sehr anstrengend. Jede Schraube hält über 30 Frames, und wir erstellen Dutzende neuer Schrauben pro Frame. Da jeder Blitz aus bis zu ein paar hundert Liniensegmenten bestehen kann und jedes Liniensegment aus drei Teilen besteht, zeichnen wir am Ende viele Sprites. Meine Demo zeichnet zum Beispiel über 25.000 Bilder pro Frame mit deaktivierten Optimierungen. Wir können es besser.

Anstatt jede Schraube bis zum Ausblenden zu zeichnen, können wir jede neue Schraube zu einem Renderziel zeichnen und das Renderziel in jedem Frame ausblenden. Das bedeutet, dass wir, anstatt jede Schraube für 30 oder mehr Frames zeichnen zu müssen, sie nur einmal zeichnen. Es bedeutet auch, dass keine zusätzlichen Leistungskosten entstehen, wenn unsere Blitze langsamer ausgeblendet werden und länger halten.

Zuerst ändern wir die LightningText-Klasse, um jede Schraube nur für einen Frame zu zeichnen. Deklarieren Sie in Ihrer Game-Klasse zwei RenderTarget2D-Variablen: currentFrame und lastFrame. Initialisieren Sie sie in LoadContent() wie folgt:

Beachten Sie, dass das Oberflächenformat auf HdrBlendable eingestellt ist. HDR steht für High Dynamic Range und bedeutet, dass unsere HDR-Oberfläche eine größere Farbpalette darstellen kann. Dies ist erforderlich, da das Renderziel dadurch Farben aufweisen kann, die heller als Weiß sind. Wenn sich mehrere Blitze überlappen, benötigen wir das Renderziel, um die volle Summe ihrer Farben zu speichern, die sich über den Standardfarbbereich hinaus summieren können. Obwohl diese heller-als-weißen Farben weiterhin als Weiß auf dem Bildschirm angezeigt werden, ist es wichtig, ihre volle Helligkeit zu speichern, damit sie korrekt ausgeblendet werden.

XNA-Tipp: Beachten Sie auch, dass Sie das XNA-Projektprofil auf Hi-Def setzen müssen, damit HDR-Blending funktioniert. Sie können dies tun, indem Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt klicken, Eigenschaften auswählen und dann das HD-Profil auf der Registerkarte XNA Game Studio auswählen.

Bei jedem Frame ziehen wir zunächst den Inhalt des letzten Frames auf den aktuellen Frame, jedoch leicht abgedunkelt. Anschließend fügen wir alle neu erstellten Schrauben zum aktuellen Frame hinzu. Schließlich rendern wir unseren aktuellen Frame auf dem Bildschirm und tauschen dann die beiden Renderziele aus, sodass sich lastFrame für unseren nächsten Frame auf den gerade gerenderten Frame bezieht.


Schritt 7: Andere Variationen

Wir haben darüber gesprochen, Zweigblitze und Blitztexte zu erstellen, aber dies sind sicherlich nicht die einzigen Effekte, die Sie erzielen können. Schauen wir uns ein paar andere Variationen von Blitzen an, die Sie verwenden können.

Beweglicher Blitz

Oft möchten Sie vielleicht einen beweglichen Blitz machen. Sie können dies tun, indem Sie jedem Rahmen eine neue kurze Schraube am Endpunkt der Schraube des vorherigen Rahmens hinzufügen.

Glatter Blitz

Sie haben vielleicht bemerkt, dass die Blitze an den Gelenken heller leuchten. Dies liegt an der Additivmischung. Vielleicht möchten Sie ein glatteres, gleichmäßigeres Aussehen für Ihren Blitz. Dies kann erreicht werden, indem Sie Ihre Mischstatusfunktion ändern, um den maximalen Wert der Quell- und Zielfarben auszuwählen, wie unten gezeigt.

Rufen Sie dann in Ihrer Draw()-Funktion SpriteBatch.Begin() mit maxBlend als BlendState anstelle von BlendState.Additive auf. Die folgenden Bilder zeigen den Unterschied zwischen additiver Mischung und maximaler Mischung auf einem Blitz.

Additive BlendingAdditive BlendingAdditive BlendingMax BlendingMax BlendingMax Blending

Bei maximaler Überblendung kann sich das Licht mehrerer Schrauben oder des Hintergrunds natürlich nicht gut summieren. Wenn Sie möchten, dass die Schraube selbst glatt aussieht, sich aber auch additiv mit anderen Schrauben verschmelzen lässt, können Sie die Schraube zuerst mit max. Achten Sie darauf, nicht zu viele große Renderziele zu verwenden, da dies die Leistung beeinträchtigen kann.

Eine andere Alternative, die bei einer großen Anzahl von Schrauben besser funktioniert, besteht darin, das in die Liniensegmentbilder integrierte Glühen zu entfernen und es mithilfe eines Nachbearbeitungs-Glüheffekts wieder hinzuzufügen. Die Details zur Verwendung von Shadern und zum Erstellen von Leuchteffekten sprengen den Rahmen dieses Tutorials, aber Sie können das XNA Bloom-Beispiel verwenden, um zu beginnen. Diese Technik erfordert keine weiteren Renderziele, wenn Sie weitere Schrauben hinzufügen.


Abschluss

Blitz ist ein großartiger Spezialeffekt, um Ihre Spiele aufzuwerten. Die in diesem Tutorial beschriebenen Effekte sind ein guter Ausgangspunkt, aber es ist sicherlich nicht alles, was Sie mit Blitzen tun können. Mit etwas Fantasie können Sie alle Arten von beeindruckenden Blitzeffekten erstellen! Laden Sie den Quellcode herunter und experimentieren Sie mit Ihrem eigenen.

Wenn Ihnen dieser Artikel gefallen hat, schauen Sie sich auch mein Tutorial über 2D-Wassereffekte an.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.