XT Knowledge Base
Hauptseite | Über | Hilfe | FAQ | Spezialseiten | Anmelden

Druckversion | Impressum | Datenschutz | Aktuelle Version

Spieleentwicklung mit JavaScript - Dynamische Spielfelder

(Unterschied zwischen Versionen)

(Sourcecode)
(Zeichnen des Spielfelds)
 
Zeile 155: Zeile 155:
* [[Spieleentwicklung mit JavaScript - Einleitung]]
* [[Spieleentwicklung mit JavaScript - Einleitung]]
* Zurück zu [[Spieleentwicklung mit JavaScript - Spielfeld]]
* Zurück zu [[Spieleentwicklung mit JavaScript - Spielfeld]]
-
* Weiter zu [[Spieleentwicklung mit JavaScript - Spielfiguren]]
+
* Weiter zu [[Spieleentwicklung mit JavaScript - Scrollende Spielfelder]]

Aktuelle Version vom 07:33, 2. Sep. 2010

Inhaltsverzeichnis

Dynamische Spielfelder

Viele Spielfelder in Computer setzen sich aus einzelnen Elementen zusammen, die insgesamt das Spielfeld ergeben. Diese einzelnen Teile können unterschiedliche Funktionen und Attribute innehaben wie zum Beispiel "Dieses Feld kann vom Spieler betreten werden" oder "Wer auf dieses Feld kommt, wird weggebeamt".

Um ein solches Spielfeld erzeugen zu können, werden zuerst die Einzelteile benötigt, aus denen es sich zusammensetzt. Das sind sogenannte Tilesets, die alle einzelnen Elemente in einer Grafik zusammenfassen.

Datei:Tileset.png

Zum Testen bitte dieses Bild abspeichern und in einem Unterordner des Ordners ablegen, in dem sich das Script befindet. Der Name des Ordners ist 'img'.

Dieses Bild enthält 5 Teilstücke, die als Hintergrund für ein Jump'n'Run Spiel dienen können.

Sourcecode

<html>
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8">
  <title>Sample</title>
  <script type="text/javascript">
    var canvas;
    var context;
    var tiles = new Array();
    var level = new Array(
      new Array( 0,4,0,0,0,0,0,0 ),
      new Array( 2,1,1,1,1,1,1,2 ),
      new Array( 2,0,3,0,0,0,0,2 ),
      new Array( 2,0,3,0,0,0,0,2 ),
      new Array( 2,0,3,2,1,1,1,2 ),
      new Array( 2,4,3,2,0,0,0,4 ),
      new Array( 1,1,1,2,1,0,1,1 ),
      new Array( 4,0,0,2,0,0,4,0 )
    );
  
    function init()
    {
      canvas = document.getElementById("board");
      context = canvas.getContext("2d");
    
      var tileset = document.getElementById("tileset");
      context.drawImage( tileset, 0, 0 );
    
      for( var i = 0; i < 5; i++ )
      {
          tiles[i] = context.getImageData( i * 30, 0, 30, 30 );
      } 
    
      drawPlayfield( level );
    }
  
    function drawPlayfield( level )
    {
      for( y = 0; y < 8; y++ )
      {
        for( x = 0; x < 8; x++ )
        {
          context.putImageData( tiles[level[y][x]], x * 30, y * 30 );              
        }
      }
    }
  </script>
</head>
<body onLoad="init();">
    <canvas id="board" width="240" height="240" style="border:1px black solid">Dieser Browser ist nicht geeignet.</canvas>
    <img id="tileset" src="img/tileset.png" style="visibility:hidden;">
</body>
</html>

WICHTIGER HINWEIS

Wird die Seite lokal getestet, muss der Link auf das Bild eine lokale URI sein und im Browser müssen die Einstellungen geändert werden. Dazu sind folgende Schritte notwendig:

  1. Neues Tab öffnen und in der Adress-Zeile "about:config" eingeben
  2. Im Feld Filter security.fileuri.strict_origin_policy eingeben
  3. Die Einstellung mit einem Doppelklick von true auf false ändern

Vorbereiten des Tilesets

Zuerst wird das TileSet als HTML-Element geladen. In der Funktion init() greifen wir darauf zu und kopieren es in den Canvas, um es in die einzelnen Teile zerlegen zu können. Mit der Canvas-Methode GetImageData ist es möglich, einen Bildausschnitt zu kopieren, den wir dann später beliebig oft wieder einfügen können.

Die einzelnen Tiles sind 30x30 Pixel groß und es sind insgesamt 5 Teile. Folgender Code-Abschnitt erledigt diese Aufgabe:

    var tileset = document.getElementById("tileset");
    context.drawImage( tileset, 0, 0 );
    
    for( var i = 0; i < 5; i++ )
    {
        tiles[i] = context.getImageData( i * 30, 0, 30, 30 );
    }

Im Anschluss befinden sich die einzelnen Tiles im tiles-Array. Die einzelnen Tiles haben einen Index von 0 bis 4.

Definition des Spielfelds

Das Spielfeld wird jetzt einfach nur noch durch die Nummern der Tiles beschrieben, die verwendet werden sollen. Also eine Reihe von Zahlen von 0 bis 4. Diese werden in einem zweidimensionalen Array abgelegt, die der Anordnung der Felder auf dem Spielfeld entspricht.

Als Beispiel definieren wir ein Level, dass genau in das dafür vorgesehene Canvas passt - also mit 8x8 Feldern:

  var level = new Array(
    new Array( 0,4,0,0,0,0,0,0 ),
    new Array( 2,1,1,1,1,1,1,2 ),
    new Array( 2,0,3,0,0,0,0,2 ),
    new Array( 2,0,3,0,0,0,0,2 ),
    new Array( 2,0,3,2,1,1,1,2 ),
    new Array( 2,4,3,2,0,0,0,4 ),
    new Array( 1,1,1,2,1,0,1,1 ),
    new Array( 4,0,0,2,0,0,4,0 )
  );

Zeichnen des Spielfelds

Nun muss ledigleich eine Funktion erstellt werden, die diese Teilchen gemäß der Leveldefinition aneinander reiht. das ist relativ einfach:

  function drawPlayfield( level )
  {
    for( y = 0; y < 8; y++ )
    {
      for( x = 0; x < 8; x++ )
      {
        context.putImageData( tiles[level[y][x]], x * 30, y * 30 );              
      }
    }
  }

Mit einer verschachtelten Schleife werden alle einzelnen Felder durchlaufen, die Information aus der Levelbeschreibung gelesen und das entsprechende Tile an der richtigen Position angezeigt.

Beachtenswert ist dieser Ausdruck:

tiles[level[y][x]]

Werte zwischen 0 und 4 zurückgeliefert werden. Ein anderer Wert kleiner 0 oder größer 4 würde also Probleme und Fehlermeldungen verursachen. Wenn die Daten aus anderen Quellen kommen, wäre hier eine Sicherheitsüberprüfung angebracht. Damit kann sichergestellt werden, dass keine ungültigen Werte eingeschleust werden können.

  function drawPlayfield( level )
  {
    for( y = 0; y < 8; y++ )
    {
      for( x = 0; x < 8; x++ )
      {
        var tile = tiles[level[y][x]];
        if( tile >= 0 && tile <= 4 )
        {
          context.putImageData( tile, x * 30, y * 30 );
        }
      }
    }
  }

Das Ergebnis sollte genau so aussehen:

Datei:Playfield1.png