/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { // Skip XML Dtd processing XmlReaderSettings settings = new XmlReaderSettings(); settings.DtdProcessing = 0; // Read in TMX level StreamReader stream = System.IO.File.OpenText("Content/Maps/Level.tmx"); // Create XmlReader based on level stream XmlReader reader = XmlReader.Create(stream, settings); // Initialize engine with level xml engine = new Engine.Engine(this, reader); // Add engine to components Components.Add(engine); // Disable engine (Titlescreen is startup screen) engine.Visible = false; engine.Enabled = false; // Add engine to services Services.AddService(typeof(Engine.Engine), engine); // Add InputManager (Keyboard, GamePad) Components.Add(new InputManager(this)); // Add titlescreen titleScreen = new TitleScreen(this); Components.Add(titleScreen); // Add ControlManager controlManager = new ControlManager(this); Components.Add(controlManager); Services.AddService(typeof(ControlManager), controlManager); base.Initialize(); }
/// <summary> /// Constructor. Parses the LAYER part of the TMX map file. There can be many layers. /// </summary> /// <param name="xml">Assumes the LAYER part of the tmx map file</param> /// <param name="engine"></param> /// <param name="tileSet"></param> public Layer(XmlReader xml, Engine engine, TileSet tileSet) { // Move xml ahead xml.Read(); // Read in layer name _name = xml.GetAttribute("name"); // Read in layer width and height _width = int.Parse(xml.GetAttribute("width")); _height = int.Parse(xml.GetAttribute("height")); // Parse the layer block while (xml.Read()) { switch (xml.Name) { // We currently only support the data block for tile layers, properties are thus ignored case "data": // We create a byte buffer to read in the base64 encoded data, which may or may not be compressed int dataSize = (_width * _height * 4) + 1024; var buffer = new byte[dataSize]; if (xml.CanReadBinaryContent) { // Read base64 content info buffer xml.ReadElementContentAsBase64(buffer, 0, dataSize); // We create a memory stream of the buffer Stream stream = new MemoryStream(buffer, false); // At this point it would be natural to check for gzip, zlib or uncompressed xml data since these are all options in Tiled // However, due to time constraints I've only implemented the default setting, zlib compressed base64 encoded data. // The first two bytes are Zlib specific identifiers, we skip those before decompressing stream.ReadByte(); stream.ReadByte(); stream = new DeflateStream(stream, CompressionMode.Decompress); // At this point we have a decompressed base64 stream which we need to "parse". // For that we use a binary reader to read out the tile ids within the layer. // In pure XML, layer data is just a long list of tile ids which represent the tile within the tileset used. // So we need to loop through the layer width by height, as each tile is listed in this order. using (stream) using (var br = new BinaryReader(stream)) { // Loop layer height for (int y = 0; y < _height; y++) { // Loop layer width for (int x = 0; x < _width; x++) { // tileId represent the tile in the tileset int tileId = br.ReadInt32(); // Tile id 0 means nothing was "painted" in this tile so we skip that. if (tileId > 0) { // Get the TileSetTile using the id we extracted TileSetTile t = tileSet.getTileById(tileId); if (t is TileSetTile) { // At this point we check if this tile has a collidable property, if so, we create a new collidable and add to the engine collidable list. if (t.getProperty("Collidable") is string && t.getProperty("Collidable").Equals("True")) { engine.AddCollidable( new Collidable( new Rectangle( x * tileSet.tileWidth, y * tileSet.tileHeight, tileSet.tileWidth, tileSet.tileHeight ) ) ); } // Add the new layertile to the layer list of tiles _layerTiles.Add(new LayerTile(t, x, y)); } } } } } } break; } } }