Generierung des Spielfeldes in Silverlight

erstellt am 09. Oktober 2007 um 19:38

Nach der Theorie - und einer etwas längeren Pause - folgt nun die Praxis.

Visual Studio 2008 Beta 2 Projekt zum Download: SilvrGame_Map_Source.zip

Starte dein Visual Studio 2008 Beta 2 und erzeuge ein neues Silverlight Projekt mit dem Namen SilvrGame_Map. Nachdem Visual Studio dein Projekt erzeugt hat, siehst du den Quelltext deiner Page.xaml Datei vor dir. Wie zu vermuten war, absolut unspektakulär. Nur um auf Nummer sicher zu gehen, ändere in dieser Datei den Wert Background Attributes von White auf Black und starte eine neue Debugger Instanz. Sollte sich ein Browserfenster öffnen und dir ein schwarzen Rechteck darstellen, dann kannst du dir sicher sein, dass deine Silverlight Installation noch intakt ist ;-)

Das Gröbste wäre damit auch schon getan, der Rest ist nur noch die Theorie aus dem vorherigen Beitrag in die Praxis umzusetzen. Kleinigkeit!
Es hat sich herauskristallisiert, dass wir vorerst zwei Objekte für die Generierung des Spielfeldes benötigen: die Kachel (Tile) und das Spielfeld (Map) ansich. Füge also deinem Projekt eine neue Klasse mit dem Namen TileBase hinzu und schreibe folgenden Code rein:

Die Klasse TileBase bildet das Grundgerüst für jede Kachel, die wir in unserem Spiel generieren. Die Kachel erstellst du nachher in Expression Blend als UserControl. Aus diesem Grund leiten wir TileBase von Control und nachher das UserControl aus Blend von TileBase ab. Dazu aber später mehr.
Da ein Control von Haus aus die Eigenschaften Width und Height mitbringt, hast du deine Klasse nur um zwei weitere Eigenschaften, nämlich m_walkable und m_position, ergänzt. Durch das Property Position stellen wir nur sicher, dass jede erstellte Kachel an ihrem linken, oberen Eck ausgerichtet wird. Dies erleichtert uns nachher die Platzierung der Kacheln auf dem Spielfeld.

Das Grundgerüst steht, nun ist es an der Zeit deiner Kachel ein Gesicht zu verpassen. Klicke im Solution Explorer mit der rechten Maustaste auf Page.xaml und wähle Open in Expression Blend… aus. Hast du zuvor Expression Blend installiert, dann öffnet sich nun dein Silverlight Projekt in Expression Blend. Ist dem nicht so, dann installiere es jetzt, starte dein Visual Studio nach der Installation neu und führe den Schritt erneut aus. Vor dir erscheint nun ungefähr dasselbe Fenster, wie das hier:

Expression Blend

Ich werde hier auf die Funktionalität von Expression Blend nicht näher eingehen, dazu gibt es im www einige Tutorials.
Du siehst hier nun deine Page.xaml Datei, nichts was dich vom Hocker reißen sollte :-) Um ein UserControl zu erstellen, klicke einfach auf File, dann New Item… und wähle Silverlight UserControl aus. Gebe als Namen Tile.xaml ein und bestätige deine Eingabe mit einem Klick auf OK.

Expression Blend UserControl

Jetzt zeichnest du dir deine Kachel, dazu musst du

  1. In der Tool Palette das Rectangle Werkzeug auswählen, dann im mittleren Bereich des Bildschirms (deiner Arbeitsfläche) ein Recht einzeichnen. Kümmere dich vorerst nicht um die Eigenschaften des Rechtecks.
  2. Im Object and Timeline Panel siehst du dann neben dem UserControl noch ein weiteren Eintrag: Rectangle. Markiere das UserControl (wenn es gelb umrahmt ist, ist es markiert) und benenne es von UserControl in Tile um. Dasselbe machst du mit dem Rectangle Objekt. Dieses benennst du, wie auf dem Bild zu sehen ist, in Body um.
  3. Die Fülleigenschaft belässt du bei weiß, hier änderst du nur die Farbe des Randes (Stroke) in ein etwas dunkleres grau um.
  4. Im Layout Panel widmest du dich den Eigenschaften des Rechtecks. Eine Breite und Höhe von 40 Einheiten ist für unser Vorhaben durchaus OK. Die Ausrichtung setzt du auf Auto. Sie wird nachher per Code angepasst.

So schnell erstellt man sich ein UserControl in Expression Blend. Ok, es ist nichts Aufwendiges, aber was nicht ist, kann vielleicht noch werden ;-) Speichere dein Projekt in Expression Blend ab und wechsle dann zu Visual Studio, welches dich eleganter weise daraufhinweist, dass sich etwas an deiner Projektstruktur geändert hat und du diese nachladen kannst, sofern du möchtest. Und Ja, du möchtest :-) Sofort erscheint in deinem Solution Explorer ein neues Objekt, nämlich Tile.xaml und darunter Tile.xaml.cs. Diese öffnest du in deinem Editor und schreibst folgenden Code rein:

Wie schon oben erwähnt, lassen wir unser UserControl nicht von Control, sondern von TileBase erben und geben ihm unsere ergänzten Eigenschaften, wie ob es begehbar ist und dessen Position. Für unsere Kachel brauchen wir neben dem FrameworkElement m_root, welches die Kachel als Ganzes abbildet, noch ein Rectangle Objekt m_body, das wir mit dem gezeichneten Rechteck aus Expression Blend im Konstruktor der Klasse referenzieren.

Als Übergabeparameter bekommt der Konstruktor einmal einen boolschen Wert, ob die Kachel begehbar ist oder nicht und ein Punkt zum Positionieren der Kacheln. Nach der Initialisierung und Referenzierung der Elementen unser Kachel, muss nur noch geprüft werden, ob die Kachel für den “Held” als nicht begehbar deklariert wurde, ist dies der Fall, so färben wir die Kachel schwarz. Zum Schluss wird die Kachel noch an ihre richtige Stelle positioniert.

Der zweite Konstruktor wird um die Kachelgröße ergänzt. Sprich, durch den Aufruf dieses Konstruktors können wir die Größe der Kachel per Code ändern, so kann es durchaus vorkommen, dass wir nicht die Default-Kachel von 40 x 40 Einheiten haben wollen, sondern vielleicht Kacheln der Größe 25 x 25 Einheiten.

Ein weiterer, noch wichtigerer Grund ist, dass die Spielfeldklasse die Kachelgröße verwaltet und somit entscheidet, wie groß/klein die Kacheln erzeugt werden.
Somit wäre unsere Kachel soweit fertig. Machen wir uns endlich an das Spielfeld ran. Hierzu fügst du deinem Projekt eine neue Klasse hinzu, nämlich Map. Wie gerade erwähnt, verwaltet das Spielfeld die Größe jeder Kachel und bekommt deswegen diese Eigenschaft als Attribut - m_tileSize. Desweiteren muss das Spielfeld wissen, auf welchen Canvas Objekt es die Kacheln legen soll. Hierzu bekommt es ein ein Canvas Objekt - m_parentCanvas - als Attribut. Was noch bleibt ist neben einem Container für die generierten Kacheln - hier ein Array m_mapTiles - noch das Spielfeldformat - m_map. Das Spielfeldformat gibt die gibt unserer Karte die richtige Struktur, es legt fest, welche Kacheln begehbar sind und welche nicht. Zusätzlich entscheidet es über die Größe des Spielfeldes und der Anzahl der darin vorkommenden Kacheln.

Jetzt fehlt uns nur noch der Konstruktor, der die Spielfeldattribute initialisiert und eine Methode - BuildMap() - zur Generierung des Spielfeldes.

Ich habe der Methode BuildMap() als Übergabeparameter einen boolschen Wert mitgegeben, der festlegt, ob das Spielfeld sowohl horizontal als auch vertikal zentriert dargestellt wird. Sonst würde es oben links in der Ecke kleben und das sah für mich nicht so schön aus.

Nun hast du es aber geschafft. Zum Schluß musst du nur noch in dem Page_Loaded EventHandler der Page.xaml.cs Datei eine Instanz der Map Klasse erzeugen und ihre Methode BuildMap() mit den dazugehörigen Übergabeparametern aufrufen. Das wars dann auch schon.

Im Browser kannst du dann das Ergebnis deiner harten Arbeit betrachten :-) Im Firefox sollte es dann ungefähr so aussehen:
Firefox Screenshot

Im nächsten Artikel bringen wir ein wenig Leben ins Spiel und fügen dem Ganzen einen Held hinzu, den wir dann hoffentlich auf unsere Karte bewegen können ;-)

| #5 Kommentare einblenden »

Silverlight läuft nur mit dem Firefox

erstellt am 04. Oktober 2007 um 12:27

Komischerweise kann ich meine Silverlight Beispiele nur im Firefox begutachten. Im Internet Explorer kriege ich bei mir unter Vista den Hinweis zum Download der Runtimes und unter Windows 2003 Server [VirtualPC] bleibt die Webseite des IE’s weiß.

Eine Neuinstallation der Runtime brachte keine Erfolge. Kann mir das Phänomen leider nicht erklären, den auf der silverlight.net Webseite springt das PlugIn an und zeigt den Inhalt mit Animation an. Ist nur etwas ärgerlich das Ganze, da ich einige Tabs im FF offen habe und bei jedem Testrun, muss ich meinen Firefox schließen, weil Visual Studio eine Instanz des Browsers öffnen muss, damit ich darin debuggen kann.

Gibts da eurerseits irgendwelche Erfahrungswerte bezüglich Lauffähigkeit mit dem IE und dem Debuggen von Silverlight Projekten?

| #5 Kommentare einblenden »

Das Spielfeld (Map)

erstellt am 19. September 2007 um 21:04

Da wir die Kachel-Technik im vorherigen Artikel erklärt haben, bietet es sich nur an, diese Technik für die Generierung unseres Spielfeldes zu benutzen.

Spielfeld Wie wir an diesem Bild links erkennen können, ist das Spielfeld eine zwei dimensionale Fläche, die sich in Spalten und Zeilen untergliedern lässt. Das programmiertechnische Pendant in C# dazu wäre ein zwei dimensionales Array. Wem diese Datenstruktur nicht geläufig ist, so möchte ich ihn/sie an dieser Stelle auf die MSDN Online Bibliothek aufmerksam machen, in der Arrays ausführlich erklärt werden.

Array Spielfeld Betrachten wir unser Spiel aus der Sicht eines Arrays, so beginnt die Adressierung der Spalten und Zeilen jeweils bei 0. In unserem Beispiel besteht das Spieldfeld aus 10 Spalten und 6 Zeilen, was genau 60 Kacheln entspricht. Die blau markierte Kachel würden wir also wie folgt ansprechen:

Also halten wir fest, dass ein Spielfeld auf einer bestimmten Anzahl an Spalten und einer bestimmten Anzahl an Zeilen beruht, deren Produkt die Anzahl der benötigten Kacheln ergibt. Klingt recht einfach, oder? Und ja, das ist es auch.

Was uns also noch fehlt, sind die Kacheln. Welche Eigenschaften können Kacheln den gebrauchen?
Eine bestimmte Höhe und Breite wäre sicherlich sinnvoll. Wie sieht es mit der Eigenschaft aus, ob das Feld begehbar ist oder nicht? Denn nicht alle dargestellten Kacheln auf dem Spielfeld können von unserem Helden (Spielfigur) betreten werden. Eine Mauer oder Wasser sind je nach Spielprinzip nicht begehbar. Diese drei Eigenschaften für eine Kachel sollte uns fürs erste reichen.

Somit hätten wir schon ein wenig beschrieben, wie ein Spielfeld und die darin befindlichen Kacheln aufgebaut sind. Was ist noch fehlt, um mit dem Programmieren endlich anzufangen ist das Format des Spielfeldes. Die Frage, die sich uns an dieser Stelle stellt ist, wie speichern wir unser Spielfeld ab?
Klar in einem Array, aber woher wissen wir, welche Kachel begehbar ist und welche nicht? Wie werden diese identifiziert? In unserem Fall gestaltet sich die Lösung des Problems recht einfach. Wir unterscheiden vorerst nur zwei Zustände, begehbar oder nicht begehbar. Also würde ich die Zahl 1 für den Zustand nicht begehrbar definieren und die Zahl 0 für den Zustand begehbar.

Spielfeld begehbar Um ein Spielfeld, wie wir es hier im linken Bild sehen, aufzubauen, müssen wir für jede schwarze Kachel eine 1 und für jede weiße Kachel eine 0 schreiben. in C# sieht das folgendermaßen aus:

Man könnte das Format des Spielfeldes sicherlich auch in eine seperate Datei auslagern, sei es XML, TXT oder ein eigenes Dateiformat. Ich habe mich für das 2D Array entschieden, weil es erstens für kleine Spiele die gängiste Methode ist, zweitens es die Kollisions- und Pfadberechnung relativ einfach macht und drittens es zahlreiche Beispiele im Internet gibt, die auf dieser Methode aufbauen. Wieso sollten wir uns dann das Leben schwerer machen?

Im nächsten Artikel werden wir dann endlich anfangen unsere Gedanken in C# Code umzuwandeln. Wir konstruieren uns mit Expression Blend eine Kachel und bauen mit dieser Kachel unser erstes Spielfeld auf. Man darf also gespannt sein ;-)

| #0 Kommentare einblenden »