示例#1
0
        private Tiled.Tileset.TilePropertyList GetTileProperties(Tiled.Map map, int tileId)
        {
            foreach (Tiled.Tileset t in map.Tilesets.Values)
            {
                Tiled.Tileset.TilePropertyList props = t.GetTileProperties(tileId);
                if (props != null)
                {
                    return(props);
                }
            }

            return(null);
        }
示例#2
0
        /// <summary>
        /// Load a map from file and create collision objects for it.  Appends map horizontally if one exists.
        /// </summary>
        /// <param name="filename">File to load map from.</param>
        public void LoadOrExtendMap(string filename, bool spawnPlayer = false)
        {
            Tiled.Map map = Tiled.Map.Load(Path.Combine(Controller.Content.RootDirectory, filename), Controller.Content);

            // Destroy and re-create collision body for map.
            if (CollisionBody == null)
            {
                CreateCollisionBody(CollisionWorld, Physics.Dynamics.BodyType.Static);
            }

            Vector2 tileHalfSize = new Vector2(map.TileWidth, map.TileHeight) / 2;
            Vector2 tileSize     = new Vector2(map.TileWidth, map.TileHeight);

            bool[,] levelCollision = new bool[map.Width, map.Height];

            float defaultZVal = ZSettings.Ground;

            // 2 = collision. 1 = no collision. 0 = unknown.
            List <byte> collision = new List <byte>();

            foreach (KeyValuePair <string, Tiled.Layer> layer in map.Layers)
            {
                defaultZVal -= 0.001f;

                for (int x = 0; x < layer.Value.Width; ++x)
                {
                    for (int y = 0; y < layer.Value.Height; ++y)
                    {
                        int tileId = layer.Value.GetTile(x, y);

                        if (tileId >= collision.Count || collision[tileId] == 0)
                        {
                            Tiled.Tileset.TilePropertyList props = GetTileProperties(map, tileId);

                            // The only way to add new elements at arbitrary indices is to fill up the rest of the array.  Do so.
                            for (int i = collision.Count; i < tileId + 1; ++i)
                            {
                                collision.Add(0);
                            }

                            if (props != null && props.ContainsKey("collision"))
                            {
                                collision[tileId] = (byte)(props["collision"].Equals("true", StringComparison.OrdinalIgnoreCase) ? 2 : 1);
                            }
                            else
                            {
                                collision[tileId] = 1;
                            }
                        }

                        levelCollision[x, y] |= (collision[tileId] > 1);
                    }
                }

                float z = defaultZVal;

                if (layer.Value.Properties.ContainsKey("zindex"))
                {
                    if (!float.TryParse(layer.Value.Properties["zindex"], out z))
                    {
                        z = defaultZVal;
                    }
                }

                MapLayer ml = new MapLayer(this, map, layer.Key, z);
                ml.Position = new Vector2(m_mapStart, 0.0f);
                AddChild(ml);
            }

            // Go through collision and try to create large horizontal collision shapes.
            for (int y = 0; y < map.Height; ++y)
            {
                int  firstX       = 0;
                bool hasCollision = false;

                for (int x = 0; x < map.Width; ++x)
                {
                    if (levelCollision[x, y])
                    {
                        if (hasCollision)
                        {
                            continue;
                        }
                        else
                        {
                            hasCollision = true;
                            firstX       = x;
                        }
                    }
                    else
                    {
                        if (hasCollision)
                        {
                            hasCollision = false;
                            int tilesWide = x - firstX;
                            if (tilesWide == 1)
                            {
                                continue;
                            }

                            for (int i = firstX; i <= x; ++i)
                            {
                                levelCollision[i, y] = false;
                            }

                            AddCollisionRectangle(
                                tileHalfSize * new Vector2(tilesWide, 1.0f)
                                , new Vector2(tileSize.X * (x - (float)tilesWide / 2) + m_mapStart, tileSize.Y * (y + 0.5f))
                                );
                        }
                    }
                }

                // Create final collision.
                if (hasCollision)
                {
                    for (int i = firstX; i < map.Width; ++i)
                    {
                        levelCollision[i, y] = false;
                    }

                    int tilesWide = map.Width - firstX;
                    AddCollisionRectangle(
                        tileHalfSize * new Vector2(tilesWide, 1.0f)
                        , new Vector2(tileSize.X * (map.Width - (float)tilesWide / 2) + m_mapStart, tileSize.Y * (y + 0.5f))
                        );
                }
            }

            // Go through collision and try to create large vertical collision shapes.
            for (int x = 0; x < map.Width; ++x)
            {
                int  firstY       = 0;
                bool hasCollision = false;

                for (int y = 0; y < map.Height; ++y)
                {
                    if (levelCollision[x, y])
                    {
                        if (hasCollision)
                        {
                            continue;
                        }
                        else
                        {
                            hasCollision = true;
                            firstY       = y;
                        }
                    }
                    else
                    {
                        if (hasCollision)
                        {
                            hasCollision = false;
                            int tilesTall = y - firstY;

                            AddCollisionRectangle(
                                tileHalfSize * new Vector2(1.0f, tilesTall)
                                , new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (y - (float)tilesTall / 2))
                                );
                        }
                    }
                }

                // Create final collision.
                if (hasCollision)
                {
                    int tilesTall = map.Height - firstY;
                    AddCollisionRectangle(
                        tileHalfSize * new Vector2(1.0f, tilesTall)
                        , new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (map.Height - (float)tilesTall / 2))
                        );
                }
            }

            SpawnController.CreateSpawnPoints(map.ObjectGroups.Values, new Vector2(m_mapStart, 0.0f), spawnPlayer);
            m_mapStart += map.Width * map.TileWidth;
        }