Beispiel #1
0
        /// <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();
        }
Beispiel #2
0
        /// <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;
                }
            }
        }