Get rich and famous, be a game designer

Sprites rendern

Die Grafikdatei liegt jetzt zur Laufzeit in
Form eines Objekts vor. Damit jene Grafik
als Sprite verwendet werden kann, ist
eine Instanz der SpriteBatch-Klasse erforderlich.
Deren Konstruktor erwartet die
Referenz des GraphicsDevice-Objekts.
Der GraphicsDeviceManager offeriert
jenes Objekt über die GraphicsDevice-Eigenschaft.
Der GraphicsDeviceManager
schließlich wird über die graphics-Variable
angesprochen:

Private SpriteBatch m_oSprite = null;
protected override void LoadGraphicsContent(
bool loadAllContent)
{
m_oSprite = new SpriteBatch(graphics.GraphicsDevice);
}

Instanzen jenes Typs sind nicht an eine
spezielle Grafik gebunden. Stattdessen
besteht die Option, unter Zuhilfenahme
eines SpriteBatch-Objekts mehrere
Sprites mit „einem Rutsch“ auf den Back
Buffer zu kopieren. Die Methoden Begin
und End bilden einen gedachten Block, in
dem Aufrufe der Draw-Methode gültig
sind:

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
m_oSprite.Begin();
//Sprites rendern
m_oSprite.End();
base.Draw(gameTime);
}

Die Draw-Methode steht in einer Reihe
von Variationen zur Verfügung. Eine der
Signaturen lautet wie folgt:
Public void Draw(Texture2D texture, Vector2 position,
Color color);
Neben der Grafik fordert die Draw-Methode
eine Position und einen Farbwert
ein. Der Farbwert gewichtet die Farbkanäle
der Grafik, um diese beispielsweise
rot einzufärben. Weiß gilt als neutrale
Farbe und belässt die Grafik in dessen
Originalzustand (Abbildung 3):

Abb. 3: Darstellung eines Sprites
Transparenz

In den seltensten Fällen sollen quadratische
Objekte mithilfe eines Sprites auf
den Monitor gebracht werden. Stattdessen
weisen die Objekte unterschiedlichste
Silhouetten auf. Bitmaps sind aber immer
quadratisch. Abhilfe schafft ein Alpha-
Kanal, der die Transparenz pro Pixel widerspiegelt
und alle nicht erforderlichen
Pixel ausblendet.

Per Default führt der Aufruf von SpriteBatch.Begin dazu, dass das Objekt die
Konfiguration des Graphics Device dahingehend
abändert, dass theoretisch, ohne
eine Zeile Code schreiben zu müssen, Grafiken
transparent dargestellt werden können.
Voraussetzung ist, dass die Textur ein
Format aufweist, das einen zusätzlichen
Kanal für die Transparenz bereithält und
dass dieser Kanal mit entsprechenden
Werten gefüllt ist. Wurde das DirectX SDK
installiert, steht ein Tool namens DirectX
Texture Tool
zur Verfügung, mit dem sich
das Format der Grafik ändern und zudem
um einen Alpha-Kanal bereichern lässt.
Der Alpha-Kanal wird mit einer Graustufengrafik
gefüllt, wobei Schwarz zur
Laufzeit transparent erscheint und weiß
vollständig sichtbare Bereiche kennzeichnet.
Das Tool erzeugt daraufhin eine neue
Datei im DDS-Format (Direct Draw Surface).

Die Content Pipeline

Die Content Pipeline hat zweierlei Daseinsberechtigungen.
Zum einen erleichtert sie die
Arbeit mit diversen Dateiformaten, da das
Produkt immer ein Objekt eines bestimmten
Typs ist. Zum anderen konvertiert die Content
Pipeline alle Ressourcen in ein Format, das
die Konsole Xbox 360 versteht. Eine aufwändige
Verarbeitung der Daten entfällt und die
Ladezeiten werden verkürzt. Zudem besitzen
Konsolen lediglich einen beschränkten Befehlssatz,
sodass die Verarbeitung der Ressourcen
in den Kompiliervorgang ausgelagert
wird.

Sprite-Animationen

Wird eine Reihe von Sprites hintereinander
abgespielt, erweckt dies den Anschein
einer Animation. Diese Vorgehensweise
ist mit einem Daumenkino vergleichbar.
Sprite-Animationen dienen im 2D-Bereich
zum Beispiel der Darstellung von Explosionen
oder der Charakteranimation.
Derartige Animationen lassen sich durch
zwei Wege realisieren. Entweder werden
die Einzelbilder jeweils als Asset der Content
Pipeline hinzugefügt und durchnummeriert
oder alle Frames werden in einer
Textur hinterlegt und zur Laufzeit referenziert
– zu sehen in Abbildung 4:

Abb. 4: Eine Textur als Frames-Container

Das nachfolgende Beispiel bestreitet
den zweiten Weg. Die Logik wird in einer
Klasse gekapselt, die von DrawableGame-Component erbt, weshalb dem Konstruktor
als Minimum ein Game-Objekt
übergeben werden muss. Für eine Sprite-Animation sind zusätzliche Informationen
erforderlich:

  • Der Bezeichner des Assets
  • Die Breite bzw. Höhe eines Bildes innerhalb der Textur
  • Die abzuspielenden Bilder pro Sekunde

Sowie Breite als auch Höhe eines Bildes
speichert eine Rectangle-Struktur. Da die
X- und Y-Komponente auf 0 gesetzt ist,
selektiert die Struktur den ersten Frame
der Animation. Anhand der Bilder pro
Sekunde berechnet der Konstruktor die
Zeitperiode, die zwischen zwei Frames
liegt (Listing 1):

public SpriteAnimation(Game game, string sAsset,
int iImageWidth, int iImageHeight,
int iFramesPerSecond) : base(game)
{
m_sAsset = sAsset;
m_oSourceRect.Height = iImageHeight;
m_oSourceRect.Width = iImageWidth;
m_fTimePerFrame = 1.0f / iFramesPerSecond;
this.Enabled = false;
}
Back Buffer

Jeder Rendervorgang führt dazu, dass die
berechneten Farbwerte pro Pixel in den Back
Buffer geschrieben werden. Der Back Buffer
ist ein sequentiell aufgebauter Speicherbereich
der letztlich die Pixel der Szene speichert.
Sobald die Szene komplett ist, wird
der Inhalt des Back Buffers auf den Monitor
„kopiert“.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.