MSDN Magazin > Home > Ausgaben > 2007 > May >  Spielbereit?: Keine Grenzen für Ihre Fanta...
Spielbereit?
Keine Grenzen für Ihre Fantasie mit XNA Game Studio Express
Charles Cox and Michael Klucher

Themen in diesem Artikel:
  • Grundlagen der Spieleentwicklung
  • Das Spacewar Starter Kit
  • Hinzufügen von Features zu Spacewar
  • Anpassen von Spielgrafiken
In diesem Artikel werden folgende Technologien verwendet:
XNA Game Studio Express, Xbox 360, C#
Laden Sie den Code für diesen Artikel herunter: XNA2007_05.exe (155 KB)
Code online durchsuchen
Haben Sie beim Spielen eines Videospiels auch schon einmal gedacht: „So etwas könnte ich auch fertig bringen“? XNA™ Game Studio Express ist eine neue Spielentwicklungslösung, sowohl für Microsoft® Windows® als auch für Xbox 360™, und wendet sich hauptsächlich an Lernende, Hobbyprogrammierer und unabhängige Spielentwickler – also Sie!
Basierend auf Visual C#® 2005 Express Edition baut XNA Game Studio Express auf dem XNA-Framework auf, einer Klassenbibliothek mit verwaltetem Code, die für die Entwicklung von Spielen entworfen wurde. Das Framework optimiert den Prozess des Schreibens von Code für zwei sehr unterschiedliche Plattformen – Xbox 360 und Windows XP SP2. Tatsache ist, dass der von Ihnen geschriebene Code ohne jegliche Änderungen auf beiden Plattformen ausführbar ist.
Sie können sofort mit dem Schreiben von Spielen für Windows beginnen, indem Sie XNA Game Studio Express von MSDN® von msdn2.microsoft.com/xna herunterladen. Um Spiele auf der Konsole Xbox 360 entwickeln zu können, müssen Sie Mitglied im XNA Creators Club werden (weitere Informationen finden Sie unter msdn2.microsoft.com/bb219592.aspx). Als Mitglied haben Sie Zugriff auf Spielressourcen sowie auf exklusive XNA Creators Club-Versionen von Starter Kits.
Vor der Einführung in XNA Game Studio Express sollten Sie die Software herunterladen und installieren. Wenn Sie Hilfe beim Einrichten Ihrer Konsole Xbox 360 benötigen, finden Sie unter msdn.com/xna/videos ein Video mit entsprechenden Anleitungen. Suchen Sie nach dem Titel „Getting Started with the XNA Creators Club“.

Grundlagen der Spielentwicklung
Das Entwickeln von Spielen ist mit einigen Herausforderungen verbunden, die sich nur in diesem Arbeitsbereich stellen. Spiele müssen darauf abzielen, die Spieler zu fesseln, nicht nur was Design angeht, sondern auch technisch gesehen. Dies wird mit ins Auge springenden Grafiken erzielt, wobei angemessene Bildfrequenzen eingehalten werden. Weitere Anforderungen sind intuitive Möglichkeiten für den Benutzer, mit dem Spiel interaktiv umzugehen, sowie Audioausgaben hoher Qualität.
Vor der Einführung von XNA Game Studio Express haben Spielentwickler Technologien, wie z. B. DirectX® und OpenGL, genutzt. Diese APIs ermöglichen im Wesentlichen Zugriff auf die Hardware, sind jedoch nicht intuitiv. Demzufolge haben die Entwickler Kernkomponenten, wie z. B. Grafiken, Audio und Eingabe, in ein Framework, das Modul genannt wird, eingebaut und anschließend die konkrete Spiellogik über dieses Framework programmiert. Das Erstellen und das Verwenden dieser Abstraktion ist oft teuer und zeitaufwändig.
Außerdem ist das Verwalten von Speicher und Logik in C++, die Sprache der Wahl für die Entwicklung von Spielen, technisch recht anspruchsvoll. Dies gilt auch für die vielen verschiedenen künstlerischen Inhalte, die in einem Spiel zu finden sind. Es verwundert daher nicht, dass für Hobbyentwickler das Entwickeln von Spielen besonders entmutigend war und ist. Ähnlich entmutigend sind die komplexen technischen und wirtschaftlichen Anforderungen beim Entwickeln von Spielen für Spielkonsolen der nächsten Generation, z. B. für die Xbox 360.
Steigen Sie bei XNA Game Studio Express ein, das auf C# 2005 Express Edition basiert. XNA Game Studio Express wurde für Hobbyprogrammierer, Lernende und alle Anhänger der Spielentwicklung entworfen und versetzt sie in die Lage, ihre eigenen Spiele zu entwickeln, sowohl für Windows als auch für Xbox 360. Dabei werden C# und die integrierte Entwicklungsumgebung Visual C# 2005 Express Edition genutzt.
XNA Game Studio Express beinhaltet das XNA-Framework, eine plattformübergreifende Spielentwicklungs-API sowohl für Windows als auch für Xbox 360. Das XNA-Framework vereinfacht nicht nur drastisch den Umgang mit Grafik, Audio, Eingaben und Speicher, sondern auch mit den fundamentalen Timing- und Bildaufbauschleifen, die in allen Spielen zu finden sind.
Außerdem enthalten in XNA Game Studio Express ist die in die Buildumgebung von Visual C# 2005 Express Edition integrierte XNA Framework Content Pipeline. Mit der Content Pipeline können Spielentwickler jetzt ihren künstlerischen Inhalt, wie z. B. 3D-Modelle, Grafiktexturen, Shader und Audio, in der IDE in ihre Lösung einfügen, und dieser Inhalt wird in Laufzeitobjekte integriert, auf die als Code zugegriffen werden kann. Dadurch wird der mit künstlerischem Inhalt verknüpfte Aufwand verringert.
Frühere Lösungen für die Spielentwicklung fingen typischerweise bei Null an: manuelles Schreiben von Timing- und Renderschleifen, die jeden einzelnen Zeittakt verwalten und sicherstellen, dass die Spielhandlung ordnungsgemäß abgehandelt wird. XNA Game Studio Express stellt die Timing- und Renderschleifen automatisch zusammen. Sie verfügen über eine Klasse „Game“, die ihr eigenes Timing und Rendering abhandelt. Dadurch wird eine Methode „Update“ offen gelegt, mit der Sie Objekte für die Aktualisierung der einzelnen Frames hinzufügen können, und eine Methode „Draw“, mit der Sie Objekte für die Darstellung auf dem Bildschirm hinzufügen können.
Des Weiteren sorgt das zugehörige Spielframework mit der Bezeichnung „Application Model“ automatisch für die Einrichtung des geeigneten Grafikgeräts, wobei kein komplizierter Gerätenummerierungscode benötigt wird. Mit diesem Code kann ein XNA Game Studio Express-Projekt kompiliert und ausgeführt werden, mit einer rundum funktionierenden Timing- und Renderschleife, die vom Augenblick der Erstellung an ausführbar ist.

Das Spacewar Starter Kit
Zusätzlich zu XNA Framework-Codevorlagen enthält XNA Game Studio Express das Spacewar Starter Kit – ein voll funktionsfähiges Spiel, mit vollständigem Quellcode und mit künstlerischen Ressourcen, die Sie modifizieren können. Das Spacewar Starter Kit ist ein Top-Down-Spaceshooterspiel für zwei Spieler, basierend auf der ursprünglichen Implementierung von Spacewar, entwickelt im Jahr 1962 von Stephen Russell, Peters Samson und Dan Edwards für die DEC PDP-1. Das Starter Kit beinhaltet zwei Versionen des Spiels: eine Version „Retro“, in der das Gameplay und die Grafiken des Originals enthalten sind, und eine Version „Evolved“, die über weiterentwickelte 3D-Grafiken und Sounds verfügt.
Wir werden das Starter Kit öffnen, die Version „Evolved“ ausprobieren, erläutern, wie das Spiel aufgebaut ist, und anschließend neue Features hinzufügen: einen Schild, mit dem sich jeder Spieler kurzzeitig gegen feindliche Geschosse schützen kann.
Starten Sie zuerst XNA Game Studio Express, klicken Sie auf das Menü „Datei“, und klicken Sie anschließend auf „Neues Projekt“. Wenn das Fenster „Neues Projekt“ angezeigt wird, klicken Sie auf „Spacewar Windows Starter Kit“ und anschließend auf „OK“ (siehe Abbildung 1). Wenn Sie dem Creators Club beigetreten sind und Ihre Xbox 360 für den Empfang von XNA Game Studio Express eingerichtet haben, klicken Sie stattdessen auf „Spacewar Xbox 360 Starter Kit“ und anschließend auf OK.
Abbildung 1 Öffnen des Spacewar Starter Kits (Klicken Sie zum Vergrößern auf das Bild)
Der Ladevorgang des Spacewar Starter Kits dauert einen Moment. Nachdem das Kit vollständig geladen ist, können Sie im Bereich „Projektmappen-Explorer“ die Codedateien sehen. Außerdem wird eine Spielanleitung für das Spiel angezeigt. Um den maximalen Spielspaß zu erleben, schließen Sie zwei Xbox 360-Controller an. Sie können mithilfe der Tastatur spielen. Die Steuerelemente werden nach dem Laden des Spacewar Starter Kits auf der Anleitungsseite aufgeführt.
Kompilieren Sie die Anwendung „Spacewar“, und führen Sie die Anwendung aus. Drücken Sie dazu F5. Nachdem das Spiel gestartet wurde, wählen Sie den Modus „Evolved“, und probieren Sie das Gameplay ein wenig aus.

Verstehen der Spielschleife
Eines der zentralen Features, die von XNA bereitgestellt werden, ist das Spielloop. Dieses Loop aktualisiert kontinuierlich den Status des Spiels (basierend auf Benutzereingabe, Bedingungen während des Spiels und anderen maßgeblichen Bedingungen) und rendert das Spiel (dazu gehören das Zeichnen auf dem Bildschirm, die Wiedergabe des entsprechenden Audios, das Bewegen eines Controllers und das Bereitstellen sonstiger Formen von Output an den Spieler). Das Verstehen der Funktionsweise der Spielschleife in Spacewar erleichtert Ihnen das Verständnis für einige der Änderungen am Starter Kit, die wir in diesem Artikel vornehmen werden.
Die Ausführung des Spiels beginnt, wie jede andere .NET-Anwendung, mit einer Methode „Main“. Die Methode „Main“ erzeugt einfach eine Instanz der Klasse „SpacewarGame“ und ruft die Methode „Run“ ihrer Basisklasse auf:
static void Main(string[] args)
{
    using (SpacewarGame game = new SpacewarGame())
    {
        game.Run();
    }
}
Beachten Sie, dass „SpacewarGame“ aus der Klasse „Game“ im Microsoft.Xna.Framework-Namespace abgeleitet ist. Diese Klasse stellt grundlegende Methoden, Eigenschaften und Ereignisse für den Lebenszyklus des Spiels zur Verfügung. Anschließend überschreiben Sie Methoden von „Game“, um Ihre eigene Funktionalität für Ihr Spiel bereitzustellen. Zum Beispiel überschreibt SpacewarGame die Methode „BeginRun“ (die von „Run“ aufgerufen wird), um die Titelmusik des Spiels wiederzugeben, den internen Statusmechanismus in den Status des Logobildschirms zu ändern und die Anfangskamera anzulegen, mit der ein Spieler alles sehen kann.
Die ChangeState-Methode von SpacewarGame, aufgerufen von der Methode „BeginRun“, ist für das Erzeugen einer Vielzahl der im Spiel verwendeten Objekte verantwortlich. Wenn die Methode „BeginRun“ die Methode „ChangeState“ mit GameState.LogoSplash als Argument aufruft, reagiert die Methode mit dem Erstellen eines TitleScreen. TitleScreen wird von FullScreenSplash abgeleitet und diese wiederum aus der im Projekt „Spacewar“ definierten abstrakten Klasse „Screen“. Die Screen-Klasse stellt eine Rendereinheit des Spiels dar, wie z. B. einen Begrüßungsbildschirm, einen Auswahlbildschirm oder eine konkrete Spielebene. Die Klasse stellt verschiedene virtuelle Methoden zur Verfügung, deren abgeleitete Typen die screenspezifische Funktionalität überschreiben. TitleScreen überschreibt die Methode „Screen.Update“, um zu prüfen, ob der Benutzer A, B oder X gedrückt hat, um den nächsten Schritt des Spiels vorzugeben (Evolved, Retro oder Info). TitleScreen ist lediglich einer von mehreren von „Screen“ abgeleiteten Typen, die in Spacewar verwendet werden. Weitere Typen sind SelectionScreen (für die Auswahl des Schiffs), EvolvedScreen (für das Spielen der Version „Evolved“), VictoryScreen (wenn ein Spieler gewonnen hat) usw.
Jeder „Screen“ kapselt den Zustand, der für die Funktionalität dieses Bildschirms notwendig ist, und das Aktualisierungs- und Renderverhalten eben dieses Bildschirms. Sowohl EvolvedScreen als auch RetroScreen, die den Spielverlauf des Hauptspiels für ihre jeweiligen Spieltypen darstellen, werden von SpacewarScreen abgeleitet:
public class SpacewarScreen : Screen
{
    protected Projectiles bullets;
    protected Ship ship1;
    protected Ship ship2;
    protected SceneItem sun;
    protected Particles particles;
    protected SceneItem backdrop; 

    protected bool paused = true;
    protected int player1Score;
    protected int player2Score;

    ...
}
SpacewarScreen enthält Elemente, die auf dem Bildschirm gerendert werden müssen. Dazu gehören SceneItems für beide Schiffe (implementiert als „Ship“, abgeleitet von „SpacewarSceneItem“, wiederum abgeleitet von der Basisklasse „SceneItem“), alle verschiedenen Partikel und Geschosse, die gerendert werden müssen, das Hintergrundbild für das Spiel, die Sonne usw. Ebenfalls enthalten ist der Spielstatus, wie z. B. die Spielstände der Spieler und ob das Spiel angehalten wurde.
Wenn ein „Game“ erzeugt wird (in unserem Fall ein SpacewarGame), wird sichergestellt, dass ein Host für die Unterbringung des Spiels und für das Bereitstellen von Diensten auf Anwendungsebene (und zwar Benachrichtigungen zu Ereignissen wie z. B. Aktivierung, Deaktivierung, Beenden und Leerlauf) für das Spiel angelegt wird. Das Letztgenannte ist am wichtigsten. Die Methode „Game.Tick“ wird von diesem Leerlaufhandler aufgerufen, und die Methode „Tick“ wiederum ruft die Methoden „Game.Update“ und „Game.DrawFrame“ auf. Die Methode „Game.Update“ wird durch Spacewar.Game.Update überschrieben, die „Update“ mit der zurzeit (durch die Methode „ChangeState“) eingestellten gültigen Szene aufruft. Game.DrawFrame ruft Game.Draw auf, die von SpacewarGame überschrieben wurde, um „Render“ für die zurzeit aktuelle Szene aufzurufen.

Schilde hoch!
Es ist nicht schwer, Spacewar mit neuen Features auszuschmücken. Im Folgenden soll ein Energieschild hinzugefügt werden. Dieser Schild schützt ein Schiff vor Schäden, die von anderen Elementen in der Szene verursacht werden können. Dazu müssen zwei Codedateien bearbeiten werden: Ships.cs und SpacewarScreen.cs. Sie können diese Dateien von msdn.microsoft.com/msdnmag/code07.aspx herunterladen oder dort durcharbeiten.
In der Datei Ship.cs wird der größte Teil der Programmierarbeit geleistet. In Spacewar definiert die Datei Ship.cs ein Objekt „Ship“. Das Objekt „Ship“ enthält Methoden und Daten, durch die ein von einem Spieler gesteuertes Raumschiffobjekt definiert wird. Suchen Sie in Solution Explorer nach Ship.cs, und doppelklicken Sie auf die Datei, um die Datei zu öffnen.
Zuerst müssen wir ein paar Variablen definieren, um die Logik des Schildes zu kontrollieren. Der Schild wird fünf Sekunden lang aktiv bleiben und kann nur ein einziges Mal je Runde verwendet werden. Gehen Sie in Ship.cs zu Zeile 40, und fügen Sie den folgenden Code ein (Sie fügen diesen Code zwischen die anderen „private members“ ein, in denen bestimmte Informationen gespeichert werden, z. B. ob das Schiff derzeit unverwundbar, „inHyperspace“ oder „inRecovery“ ist):
private bool inShield;
private bool shieldUsed;
private double exitShieldTime;
private const double shieldTime = 5.0;
Dadurch werden einige Variablen eingerichtet, in denen nachverfolgt wird, ob der Schild aktiv ist, ob der Schild bereits verwendet wurde und wie viel Zeit noch bis zum Ablauf des Timers des Schildes verbleibt.
Verwenden wir am besten eine Eigenschaft, damit wir auf einfache Weise abrufen können, ob der Schild des Schiffs aktiv ist. Der Zugriff erfolgt durch unsere Änderungen in „SpacewarScreen.cs“, die wir in Kürze vornehmen werden. Gehen Sie in Ship.cs zu Zeile 188 (was jetzt, nach Hinzufügen des vorherigen Codeabschnitts, Zeile 188 ist), und fügen Sie den folgenden Code hinzu:
public bool Shield { get { return inShield; } }
Bis hierher wurde ein Satz von Variablen und ein Accessor eingerichtet. Nun sollen diese Variablen mit Spielaktionen verbunden werden. Dabei wird die Methode „Update“ in Ship.cs geändert. Wie bereits erläutert, wird die Methode „Update“ von „Ship“ vom Aufruf „Update“ das Spielloop aufgerufen, die automatisch einmal je Frame (oder öfter, abhängig davon, wie schnell das Spiel läuft) vom XNA Framework-Anwendungsmodell aufgerufen wird. „Update“ ist die Methode, mit der Sie die Objekte des Spiels herumbewegen, miteinander in Interaktion treten lassen und Eingaben von Spielern erfassen (was in dieser Methode „Update“ hier vorgenommen wird).
Im nächsten Schritt muss die Update-Methode von „Ship“ geändert werden, um auf die Eingabe des Spielers zum Aktivieren des neuen Schildes zu reagieren. Gehen Sie in Ship.cs zu Zeile 248, die sich in der Update-Methode direkt vor dem Test von „if (inHyperspace)“ befindet, und fügen Sie den folgenden Code ein:
if (XInputHelper.GamePads[player].XPressed && !shieldUsed)
{
    inShield = true;
    shieldUsed = true;
    exitShieldTime = shieldTime;
    Sound.PlayCue( Sounds.PhaseActivate );
}
Eine einzige Eingabezeile, angezeigt in der bedingten Anweisung, ist alles, was benötigt wird, um auf einen Tastendruck auf der Tastatur oder am Controller zu prüfen. XInputHelper, bereitgestellt im Spacewar Starter Kit, stellt einen Wrapper sowohl für den Xbox 360-Controller als auch für Tastatureneingaben zur Verfügung und vereinfacht dadurch Eingaben. Mithilfe von XInputHelper prüft diese IF-Anweisung, ob von dem Spieler, dem das Schiff gehört, die Taste „X“ gedrückt wurde. Wenn Sie über die Tastatur spielen, lautet die entsprechende Taste „F“ für Spieler 1 und „Bild nach oben“ für Spieler 2.
Sie können diese Tastenzuordnungen auf einfache Weise ändern, indem Sie die Datei settings.xml im Projekt „Spacewar“ modifizieren. settings.xml ist eindeutig zu Spacewar zugeordnet (die Datei wird in der von SpacewarGame überschriebenen Methode „Game.Initialize“ geladen), aber XML-Datendateien sind im Allgemeinen eine gute Wahl für Spieldaten. Da XNA Game Studio Express auf dem .NET Framework aufbaut, ist der Xml-Namespace für Spiele sichtbar.
Der Code innerhalb der Bedingung baut den Schild auf, markiert den Schild als in dieser Runde benutzt und startet den Timer für den Schild. Außerdem verwendet der Code das Audiosystem von XNA-Framework, um einen Auslöser abzuspielen, der wiederum einen Sound für den Spieler wiedergibt. Spacewar abstrahiert die Audioschicht von XNA-Framework mithilfe von Enumerationswerten, wie z. B. Sounds.PhaseActivate, um die abzuspielenden Audioauslöser zu benennen. Im Allgemeinen rufen Sie Auslöser mithilfe eines Zeichenfolgenwerts auf. Wenn die Anzahl der Auslöser in Ihrem Spiel begrenzt ist, wie z. B. in Spacewar, ist eine Enumeration eine gute Lösung, besonders wenn sich Auslösernamen während der Weiterentwicklung ändern.
Sounds fügen Sie einem Spiel mithilfe des Microsoft Cross-Platform Audio Creation Tool (XACT), enthalten in XNA Game Studio Express, hinzu. Alle Audiodateien und ihre zugeordneten Auslöser sind in einem XACT-Projekt enthalten. Dieses Projekt wird in einer grafischen Benutzeroberfläche angezeigt, in der Sie Sounds durch Drag & Drop in das Projekt einbringen können. Wenn Sie Ihr Spiel kompilieren, lädt die XNA Framework Content Pipeline das XACT-Projekt und erstellt die benötigten Audiodateien. Wenn Sie einen Sound in Spacewar hinzufügen möchten, müssen Sie die zusätzlichen Schritte zum Hinzufügen des Auslösernamens in das Array der Auslösernamen und zum Vorgeben eines Enumerationswerts für den Sound-Index im Array der Auslösernamen ausführen. Danach können Sie Ihren Sound mithilfe der Enumeration „Sounds“ aufrufen.
Im Aufruf „Update“ möchten Sie sicherlich die notwendige Logik für den Timer des Schildes bei aktiviertem Schild einfügen. Gehen Sie zu Zeile 348 am Ende des Blocks „if (!Paused)“, und fügen Sie den folgenden Code ein:
if (inShield)
{
    exitShieldTime -= elapsedTime.TotalSeconds;
    if (exitShieldTime <= 0)
    {
        inShield = false;
        Sound.PlayCue( Sounds.PhaseExpire );
    }
}
Dieser Code vermindert einfach die für den Schild verbleibende Zeit um die bereits abgelaufene Zeit. Die bereits abgelaufene Zeit ist ein Maß für die zwischen den Aufrufen an „Update“ vergangene Zeit. Dieser Betrag, angewendet auf Spiellogik, wie z. B. Bewegungen oder Timer, simuliert den Ablauf der Zeit und wird durch das XNA-Framework an „Update“ übergeben. Wenn die Zeit für den Schild abgelaufen ist, wird der Schild deaktiviert und ein entsprechender Sound wird wiedergegeben.

Rendern von Details
Nachdem wir Eingabe und Sound geschickt gelöst haben, bleibt noch eine Frage: Wie soll der Schild aussehen? Dazu muss ein Code in die Methode „Render“ eingefügt werden. Mithilfe einiger Mathe- und Zeichnungsfunktionalität, die im XNA-Framework bereitgestellt wird, wird ein Sprite - eine 2D-Textur mit Transparenz – über die 3-D-Position des Schiffs gezeichnet.
Gehen Sie im Projektmappen-Explorer zum Ordner „Content“ in der Lösungsstruktur, öffnen Sie den Ordner, und öffnen Sie den in diesem Ordner enthaltenen Ordner „Textures“. Sie sehen eine Vielzahl an .tga-Dateien. Eine dieser Dateien soll als die Schildtextur verwendet werden. Eine .tga-Datei beinhaltet eine 2D-Grafik, ein Sprite.
Gehen Sie in Ship.cs zu Zeile 433, und fügen Sie direkt danach eine neue Zeile ein – nach dem Ende des Blocks für „if (showThrust && evolved“). Fügen Sie in diese neue Zeile den in Abbildung 2 angegebenen Code ein.
if (inShield && evolved)
{
    Texture2D shieldtexture = 
        SpacewarGame.ContentManager.Load<Texture2D>( 
        SpacewarGame.Settings.MediaPath + @”textures\circle” );

    batch.Begin( SpriteBlendMode.AlphaBlend );

    // Move into screen space.
    Vector3 location = device.Viewport.Project(
        position, SpacewarGame.Camera.Projection,
        SpacewarGame.Camera.View, Matrix.Identity );

    batch.Draw(
        shieldtexture,
        new Vector2( location.X - shieldtexture.Width / 2.0f, 
                     location.Y - shieldtexture.Height / 2.0f ),
        new Rectangle( 0, 0, shieldtexture.Width, shieldtexture.Height ),
        new Color( new Vector4( 0.0f, 1.0f, 0.0f, 0.5f ) ), 0.0f,
        new Vector2( shieldtexture.Width / 2.0f,
                     shieldtexture.Height / 2.0f ),
        (3.0f * (float)(Math.Abs( Math.Cos( exitShieldTime ) ))) + 2.0f,
        SpriteEffects.None, 0.0f);

    batch.End();
}
Im Folgenden wird erläutert, was in diesem Code geschieht. Zuerst lädt die Klasse „ContentManager“ mithilfe des XNA-Frameworks und der XNA Framework Content Pipeline die Textur mit dem Namen „circle“ aus dem Ordner „Content\Textures“. Die Klasse „ContentManager“ ist eine Klasse in XNA-Framework, die zur Laufzeit Inhalte aus der Content Pipeline lädt. Die Klasse ist Bestandteil des vorgefertigten Application Model-Codes in jedem neuen XNA Game Studio Express-Projekt. Der Name „circle“ ist mit der Datei circle.tga im Ordner „Content\Textures“ verknüpft. Die XNA Framework Content Pipeline weist jeder Inhaltsdatei einen aussagefähigen Namen zu, der zum Laden des Inhalts zur Laufzeit verwendet wird.
Danach wird die Textur in eine von XNA-Framework bereitgestellte Klasse Texture2D geladen. Das Objekt Texture2D wird mit Hilfe eines SpriteBatch auf dem Bildschirm dargestellt (benannter Batch in diesem Codeblock), das einen Batch an Texturen repräsentiert, die sofort auf dem Bildschirm dargestellt werden.
Es wird batch.Begin aufgerufen, um zu signalisieren, dass das Zeichnen des Sprites nun beginnen kann. Beachten Sie, dass hier Alphablending verwendet werden soll. Dadurch kann die Textur „circle“ an ihren Kanten transparent und im Inneren teilweise transparent erscheinen, da wir ja das Schiff unter dem Schild noch sehen möchten.
Vor dem Zeichnen müssen Sie wissen, an welcher Position auf dem Bildschirm die Darstellung erfolgen muss. Spacewar Evolved ist ein 3D-Spiel, Objekte bewegen sich also in drei Dimensionen und werden beim Zeichnen lediglich auf eine 2D-Ebene projiziert. Sie müssen die 2D-Position des 3D-Schiffs ermitteln, bevor Sie wissen, wo Sie den Schild zeichnen sollen.
Das XNA-Framework ermöglicht uns, diese Informationen vom Grafikgerät abzurufen. Sie rufen device.Viewport.Project auf und übergeben die 3D-Koordinaten des Schiffs sowie die Ansichtsmatrix und die Projektionsmatrix. Die Ansichtmatrix definiert die lineare algebraische Transformation, die auf jedes 3D-Objekt angewendet wird, um das Objekt relativ zum Standpunkt des Spielers korrekt zu platzieren. Die Projektionsmatrix transformiert die 3D-Koordinaten für jedes Objekt in die 2D-Bildschirmkoordinaten, anhand derer die Objekte auf dem Bildschirm dargestellt werden können. Diese Matrizen werden oftmals im Voraus berechnet und gespeichert. In Spacewar werden diese Matrizen in einer Klasse „Camera“ abgelegt, in der auch der Standpunkt des Spielers gespeichert ist. Der Aufruf von device.Viewport.Project mit diesen Werten simuliert die Transformation der Position des Schiffs zu 2D-Koordinaten, ohne das Schiff tatsächlich an der Stelle dieser Koordinaten zu zeichnen. Dieser Aufruf gibt einen Vektor zurück, der die 2D-Zeichnungskoordinaten enthält, mit denen wir unseren Schild zeichnen werden.
Der nächste Schritt besteht im Aufrufen von batch.Draw mit den folgenden Übergaben:
  • Das Objekt „Texture2D“.
  • Unsere projizierten Koordinaten minus halbe Breite und halbe Höhe des Sprites. Dadurch wird das Sprite direkt auf dem Schiff zentriert.
  • Die Quellgröße der Textur.
  • Eine Farbe, die mit den vorhandenen Farben des Sprites zu multiplizieren ist. (Sie erstellen diese Farbe als Vector4, mit drei Komponenten für jeweils Rot, Grün und Blau und einer vierten für Alpha (Undurchsichtigkeit). Diese speziellen Werte definieren ein teilweise transparentes Grün. Die Transparenz ermöglicht, das Schiff unter dem Schild zu sehen, statt es zu verdecken).
  • Ein Skalierungsfaktor. (Sie wenden hier einen Trick an und nehmen den Kosinus der verbleibenden Schildzeit, dadurch fluktuiert die Größe des Schildes in Abhängigkeit von der Zeit, und das ergibt einen grafischen Kick.)
  • Ein Spriteeffektkennzeichen, das Sie auf „None“ setzen (aber mit dem wir das Sprite horizontal oder vertikal umklappen könnten).
  • Eine Bildschirmtiefe. Durch einen Wert von Null wird das Sprite über alle anderen Objekte gezeichnet, dadurch ist gewährleistet, dass das Sprite über das Schiff gerendert wird und nicht unter das Schiff.

Energie auf die Schilde!
An dieser Stelle kann ein Spieler einen Schild aktivieren und nach einer entsprechenden Zeitspanne wieder verschwinden lassen. Leider bietet der Schild bis jetzt noch keinerlei Schutz. Um diese Funktionalität zu realisieren, öffnen Sie SpacewarScreen.cs und fügen zwei simple Codeblöcke ein, jeweils einen je Spieler. Gehen Sie in SpacewarScreen.cs zu Zeile 94, und fügen Sie den folgenden Code an den Anfang von HitPlayer2 ein:
if (ship2.Shield)
{
    // Make a bouncy sound rather than an explosion.
    Sound.PlayCue( Sounds.WeaponPickup );
    return;
}
Fügen Sie in Zeile 122 an den Anfang von HitPlayer1 außerdem Folgendes ein:
if (ship1.Shield)
{
    // Make a bouncy sound rather than an 
    // explosion.
    Sound.PlayCue( Sounds.WeaponPickup );
    return;
}
Wie weiter oben beschrieben, stellt SpacewarScreen.cs die Updatelogik für das Spielloop von Spacewar dar. Viele Spiele, einschließlich Spacewar, verwenden separate Spiellogikschleifen für die verschiedensten Zustände eines Spiels, wie z. B. Hauptmenü, Waffenauswahl und das eigentliche Spiel selbst. Während sich die Spieler durch die Spiele bewegen, werden Steuerelemente von Zustand zu Zustand gereicht. In Spacewar werden diese Zustände „Screens“ genannt und durch die Klasse „Screen“ repräsentiert. SpacewarScreen ist von „Screen“ abgeleitet und verarbeitet den eigentlichen Zustand des Spielverlaufs, in dem die zwei Spieler ihre Raumschiffe steuern und Kämpfe austragen.
In der Klasse „SpacewarScreen“ verwaltet die Update-Schleife die Spielobjekte, wie z. B. die Raumschiffe, Waffen und Asteroiden, die über den Bildschirm schweben. Wenn diese Objekte mit den Raumschiffen kollidieren, wird die Logik HitPlayer1 bzw. HitPlayer22 aufrufen, die den vom Raumschiff erlittenen Schaden berechnen.
Dieser Code ändert die Spiellogik in HitPlayer1 bzw. HitPlayer2 so, dass bei Einwirkung eines Schadensereignisses auf ein Schiff eine Überprüfung des Schildes erfolgt, bevor der Schaden auf das Schiff angerechnet wird. Wenn der Schild aktiviert ist, wird ein Abprallgeräusch wiedergegeben, und die Schadensfunktion wird ohne weiteren Auswirkungen beendet.
Das war's. Kompilieren und starten Sie das Spiel durch Drücken von F5 aus, und probieren Sie es aus! Wählen Sie im Hauptmenü den Spielmodus „Evolved“ aus. Nachdem Sie das Spiel gestartet haben, drücken Sie die Taste „X“ oder die entsprechende Taste der Tastatur („F“ für Spieler 1, „Bild nach oben“ für Spieler 2), um den Schild aufzubauen, wie in Abbildung 3 dargestellt. Beide Spieler können den Schild nur ein einziges Mal je Runde verwenden, aber der Schild ist sehr wirkungsvoll: er absorbiert Geschosse aller Art, Asteroidentreffer verursachen keinen Schaden – sogar die Sonne kann Ihnen nichts anhaben!
Abbildung 3 Schilde sind oben! (Klicken Sie zum Vergrößern auf das Bild)
Ziehen Sie mit aktiviertem Schild um die Gegend, aber achten Sie darauf, nicht zu nah an die Sonne zu gelangen, wenn der Schild abläuft, denn er hält nur fünf Sekunden lang!
Einige Ideen, wie es von hieraus weitergehen kann: Sie könnten mithilfe von etwas Vektormathematik Geschosse so ändern, dass sie vom Schild abprallen, statt absorbiert zu werden. Es wäre sicherlich eine schmerzhafte Überraschung für einen Gegner, wenn seine eigenen Geschosse zu ihm zurückfliegen! Oder ändern Sie das Schadenssystem so, dass ein Schiff mit aktiviertem Schild den doppelten Schaden verursacht, wenn es einen Gegner trifft! Rammgeschwindigkeit!
Der Spaß am Schreiben von Spielen ist ein weites Experimentierfeld. Mit XNA Game Studio Express ist es ein Leichtes, feines Tuch zu weben und ein Spiel wirklich zu einer eigenen Kreation zu machen.

Zugaben: Ändern Sie den Raum!
XNA Game Studio Express ist nicht nur eine große Hilfe für Leute, die sich darum sorgen, wie der beste Code für neue Features in ihren Spielen zu schreiben ist. Es verfügt außerdem über ein bereits oben erwähntes Featureset mit dem Namen „XNA Framework Content Pipeline“. Die XNA Framework Content Pipeline unterstützt Sie beim Erstellen von 2D-, 3D- und sogar Audioinhalt für Ihr auf XNA-Framework basierendes Spiel.
Ein Teil, den die XNA Framework Content Pipeline erledigt, ist die Integration des Prozesses für Erstellung und Kompilierung von Inhalt in Visual C# Express. Der damit verbundene zusätzliche Vorteil besteht darin, dass Sie bestimmte Arten von Inhalten direkt von Visual C# Express starten können: Sie bearbeiten den Inhalt und kompilieren anschließend erneut, um die Änderungen in Ihrem Spiel zu sehen. Durch Kompilieren Ihres Inhalts gleichzeitig mit dem Code können Sie Fehler am Inhalt entdecken, bevor Sie das Spiel ausführen.
Die XNA Framework Content Pipeline unterstützt verschiedene 2D-Grafikdateiformate, wie .bmp, .jpg, .png, .tga und .dxt. Außerdem werden zwei 3D-Dateiformate unterstützt: .x und .fbx. Beide dieser 3D-Formate verfügen über Dateiformatexporter für eine große Anzahl an sowohl frei verfügbaren als auch professionellen Tools für das Erstellen von 3D-Grafiken. Die XNA Framework Content Pipeline wurde außerdem extrem erweiterbar gestaltet. Das bedeutet, dass Sie durch Onlinesuchen möglicherweise Support für mehrere der von Ihnen bevorzugten Dateiformate finden können.
Im Folgenden wird die XNA Framework Content Pipeline anhand von Spacewar etwas näher betrachtet. Wieder in XNA Game Studio Express, gehen Sie zum Projektmappen-Explorer. Öffnen Sie den Ordner „Content“ und anschließend den Ordner „Textures“. Hier sehen Sie viele der von Spacewar verwendeten Texturen. Klicken Sie auf die Datei B1_nebula01.tga. Dies ist einer der Hintergründe, die im Spiel verwendet werden. Im Eigenschaftenraster unten im Projektmappen-Explorer sollten nun einige relevante Eigenschaften angezeigt werden (siehe Abbildung 4). Wenn Sie das Eigenschaftenraster nicht sehen können, klicken Sie mit der rechten Maustaste auf die Datei B1_nebula01.tga, und klicken Sie auf „Eigenschaften“.
Abbildung 4 Eigenschaften von Texturen 
Im Eigenschaftenraster sehen Sie mehrere einzigartigen Eigenschaften, die fest mit der XNA Framework Content Pipeline verbunden sind. Hier verwenden wir die Eigenschaft „Content Importer“. Ein Importer ist verantwortlich für das Nutzen der Quelldaten – in diesem Fall eine .tga-Datei – und für das Transformieren dieser Daten zum XNA Framework-Inhalts-DOM. Das Inhalts-DOM speichert Daten, die von den Importern transformiert und normalisiert wurden, sodass Prozessoren unabhängig von Dateiformaten arbeiten können. Die nächste Eigenschaft ist die Eigenschaft „Content Property“. Der Prozessor ist verantwortlich für das Konvertieren der Daten aus dem Inhalts-DOM in ein Objekt, das für die Verwendung zur Laufzeit geeignet ist – in diesem Fall ein Sprite. Mit Hilfe der Eigenschaft „Asset Name“ wird eine Ressource zur Laufzeit geladen. Sie können die Verarbeitung der Ressource deaktivieren, indem Sie die Eigenschaft „XNA Framework Content“ auf „false“ einstellen.
Als Nächstes kommt der Versuch, die Grafikdatei B1_nebula01.tga zu bearbeiten, um zu sehen, was sich in Spacewar ändert. Sie benötigen dazu einen Bildeditor, der eine .tga-Datei bearbeiten kann. Wenn Sie nicht über einen solchen Bildeditor verfügen, können Sie Paint.NET von getpaint.net herunterladen.
Doppelklicken Sie auf die Datei, um den mit diesem Dateityp verknüpften Editor zu starten. Nehmen Sie anschließend ein paar Änderungen in der Datei vor (siehe Abbildung 5). Eine einfache Möglichkeit in Paint.NET besteht im Ändern von Farbton und Farbsättigung. Klicken Sie dazu auf das Menü „Adjustments“ (Anpassungen) und anschließend auf „Farbton/Sättigung“. Verschieben Sie die Schieberegler, um Farbton, Sättigung und Helligkeit der Grafik zu ändern, und klicken Sie anschließend auf OK, um die Änderungen zu übernehmen. Nachdem Sie die Datei geändert haben, speichern Sie die Datei, und kehren Sie zu XNA Game Studio Express zurück. Kompilieren Sie das Projekt „Spacewar“, und führen Sie das Projekt aus. Drücken Sie dazu F5. XNA Game Studio Express erkennt, dass die Datei geändert wurde, und erstellt die Ressource neu und stellt sie neu bereit (sogar zur Konsole Xbox 360). Wenn Sie ein Spiel „Evolved“ starten, sollte der geänderte Hintergrund zu sehen sein!
Abbildung 5 Bearbeiten einer Textur in Paint.NET (Klicken Sie zum Vergrößern auf das Bild)

Heben Sie ab!
Diese einfachen Beispiele verdeutlichen nur einen Bruchteil der Leistungsfähigkeit von XNA Game Studio Express. Die plattformübergreifende Kombination von XNA-Framework und XNA Framework Content Pipeline heißt, dass Sie sich auf darauf konzentrieren können, was an der Entwicklung von Spielen den eigentlichen Spaß ausmacht: wunderbarer Inhalt und ein einfallsreiches Gameplay.
Außerdem empfehlen wir, dass Sie dem XNA Creators Club beitreten, damit Sie Ihre Fähigkeiten und Fertigkeiten in der Spielentwicklung auf die nächsthöheren Stufen ausbauen können. Eine Mitgliedschaft im Club öffnet Ihnen nicht nur Türen zum Entwickeln Ihrer eigenen Spiele auf der Xbox 360-Plattform, sondern bietet Ihnen außerdem Zugang zu exklusivem Inhalt, Beispielen, Starter Kits und vielen weiteren Ressourcen, die Ihnen helfen werden, dass aus der Idee von Ihrem Spiel Realität wird.

Charles Cox gehört der „Game Platform Documentation Group“ bei Microsoft an und bildet Entwickler aus. Zuvor war er als technischer Redakteur für DirectX und DirectX und Microsoft Game Studios tätig. Heute entwickelt und bietet Charles Cox Lernprogramme und Schulungsworkshops für XNA Game Studio Express an.

Michael Klucher ist Programm-Manager im XNA Game Studio-Team von Microsoft und arbeitet an der XNA Framework Content Pipeline und am XNA Game Launcher für die Konsole Xbox 360. Kontaktieren Sie Michael über seinen Blog unter klucher.com.

Page view tracker