Exemplo n.º 1
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="Room" /> class.
        /// </summary>
        /// <param name="color">The color of the map.</param>
        /// <param name="map">The map this room is based on.</param>
        /// <param name="gravity">The gravity of the room.</param>
        public Room(RoomType type, Color color, Map map, GraphicsDevice device, float gravity = DEFAULT_GRAVITY)
        {
            this.color = color;
            Gravity = gravity;
            this.map = map;
            Type = type;
            miniMapIsVisible = GameEngine.ShouldShowMinimap;

            width = map.WidthInPixels();
            height = map.HeightInPixels();
            background = new Background(type, width, height);

            /* Step 1: Load tiles from map. */
            tilesize = new Vector2(map.TileWidth, map.TileHeight);
            Debug.Assert(Math.Abs(map.WidthInPixels()%tilesize.X) < float.Epsilon,
                         "Map doesn't divide evenly into rows of tiles.");
            Debug.Assert(Math.Abs(map.HeightInPixels()%tilesize.Y) < float.Epsilon,
                         "Map doesn't divide evenly into columns of tiles.");

            tiles = new Tile[map.Height,map.Width];
            TileGrid grid = ((TileLayer) map.GetLayer(TILE_LAYER_NAME)).Tiles;
            for (int y = 0; y < map.Height; y++)
                for (int x = 0; x < map.Width; x++)
                {
                    TiledLib.Tile tile = grid[x, y];
                    tiles[y, x] = new Tile(new Vector2(x*tilesize.X, y*tilesize.Y), tilesize, tile, Color.White);
                }

            /* Step 2: Load objects from map. */

            /* Player */
            MapObject playerObj = map.FindObject((layer, obj) => obj.Name == PLAYER_OBJECT_NAME);
            Add(new Player(new Vector2(playerObj.Bounds.X, playerObj.Bounds.Y)));

            /* Ink Generators */
            IEnumerable<MapObject> generatorObjs = map.FindObjects((layer, obj) => obj.Type == GENERATOR_OBJECT_NAME);
            foreach (MapObject generatorObj in generatorObjs)
            {
                // get all the properties of the generator from the map object
                Property directionProperty;
                Debug.Assert(generatorObj.Properties.TryGetValue(DIRECTION_PROPERTY_NAME, out directionProperty),
                             "Generator with no direction.");
                Vector2? genDirection = VectorHelper.FromDirectionString(directionProperty.RawValue);
                Debug.Assert(genDirection != null, "Invalid direction name specified.");

                float genX = genDirection.Value.X > 0 ? generatorObj.Bounds.Right : generatorObj.Bounds.Left;
                float genY = genDirection.Value.Y < 0 ? generatorObj.Bounds.Bottom : generatorObj.Bounds.Top;

                bool isWaterGenerator = false;
                Property colorProperty;
                Color? genColor = Color.Transparent;
                Debug.Assert(generatorObj.Properties.TryGetValue(COLOR_PROPERTY_NAME, out colorProperty),
                             "Generator with no color.");
                if (colorProperty.RawValue == WATER)
                    isWaterGenerator = true;
                else
                {
                    genColor = ColorHelper.FromString(colorProperty.RawValue);
                    Debug.Assert(genColor != null, "Invalid generator color was specified.");
                }

                int genInterval = DEFAULT_GENERATOR_INTERVAL;
                Property intervalProperty;
                if (generatorObj.Properties.TryGetValue(INTERVAL_PROPERTY_NAME, out intervalProperty))
                    genInterval = FloatHelper.ParseIntervalString(intervalProperty.RawValue);

                float genSpeed = DEFAULT_GENERATOR_VELOCITY;
                Property speedProperty;
                if (generatorObj.Properties.TryGetValue(SPEED_PROPERTY_NAME, out speedProperty))
                    genSpeed = FloatHelper.ParseSpeedString(speedProperty.RawValue);

                if (!isWaterGenerator)
                {
                    Debug.Assert(genColor != Color.Transparent, "Invalid generator color specified.");
                    Add(new InkGenerator(new Vector2(genX, genY), genDirection.Value, genColor.Value, genInterval,
                                         genSpeed));
                }
                else
                    Add(new WaterGenerator(new Vector2(genX, genY), genDirection.Value, genInterval, genSpeed));
            }

            /* Portals */
            IEnumerable<MapObject> portalObjs = map.FindObjects((layer, obj) => obj.Type == PORTAL_OBJECT_NAME);
            foreach (MapObject portalObj in portalObjs)
            {
                Property colorProperty;
                Debug.Assert(portalObj.Properties.TryGetValue(COLOR_PROPERTY_NAME, out colorProperty), "Portal found with no color.");
                Color? portalColor = ColorHelper.FromString(colorProperty.RawValue);
                Debug.Assert(portalColor != null, "Invalid portal color was specified.");

                bool isCorrectPortal = false;
                Property correctProperty;
                if (portalObj.Properties.TryGetValue("Correct", out correctProperty))
                    isCorrectPortal = true;

                Vector2 portalPos = new Vector2(portalObj.Bounds.X, portalObj.Bounds.Y);
                Vector2 portalSize = new Vector2(portalObj.Bounds.Width, portalObj.Bounds.Height);

                Add(new Portal(Type, portalPos, portalSize, portalColor.Value, isCorrectPortal));
            }

            /* Spikes */
            IEnumerable<MapObject> spikeObjs = map.FindObjects((layer, obj) => obj.Type == SPIKE_OBJECT_NAME);
            foreach (MapObject spikeObj in spikeObjs)
            {
                Color? spikeColor = Color.White;
                Vector2? spikeDirection;

                Property colorProperty;
                if (spikeObj.Properties.TryGetValue(COLOR_PROPERTY_NAME, out colorProperty))
                    spikeColor = ColorHelper.FromString(colorProperty.RawValue);
                Debug.Assert(spikeColor.HasValue, "Invalid spike color specified.");

                Property directionProperty;
                Debug.Assert(spikeObj.Properties.TryGetValue(DIRECTION_PROPERTY_NAME, out directionProperty), "Spikes without direction");
                spikeDirection = VectorHelper.FromDirectionString(directionProperty.RawValue);
                Debug.Assert(spikeDirection.HasValue, "Invalid spike direction specified.");
                bool alignedHorizontally = (spikeDirection.Value.X == 0);
                bool facingLeft = (spikeDirection.Value.X < 0);
                int numSpikes = alignedHorizontally
                    ? (int)(spikeObj.Bounds.Width / (tilesize.X))
                    : (int)(spikeObj.Bounds.Height / (tilesize.Y));

                for (int i = facingLeft ? 1 : 0; i < (facingLeft ? numSpikes : numSpikes - 1); i++)
                {
                    spikes.Add(new Spike(alignedHorizontally
                        ? new Vector2(spikeObj.Bounds.X + i*tilesize.X, spikeObj.Bounds.Y)
                        : new Vector2(spikeObj.Bounds.X, spikeObj.Bounds.Y + i*tilesize.Y),
                        new Vector2(tilesize.X * 2, tilesize.Y), spikeColor.Value, spikeDirection.Value));
                }
            }

            /* Waves */
            IEnumerable<MapObject> waveObjs = map.FindObjects((layer, obj) => obj.Type == WAVE_OBJECT_NAME);
            foreach (MapObject waveObj in waveObjs)
            {
                Property colorProperty;
                Color? waveColor = Color.White;
                bool isWater = false;
                Debug.Assert(waveObj.Properties.TryGetValue(COLOR_PROPERTY_NAME, out colorProperty), "Found a wave with no color.");

                if (colorProperty.RawValue == WATER)
                    isWater = true;
                else
                {
                    waveColor = ColorHelper.FromString(colorProperty.RawValue);
                    Debug.Assert(waveColor.HasValue, "Invalid wave color specified.");
                }

                Property directionProperty;
                Vector2? direction = new Vector2(1, 0);
                if (waveObj.Properties.TryGetValue(DIRECTION_PROPERTY_NAME, out directionProperty))
                {
                    direction = VectorHelper.FromDirectionString(directionProperty.RawValue);
                }

                Add(new WaveGenerator(new Vector2(waveObj.Bounds.X, waveObj.Bounds.Y + (1f/2f)*waveObj.Bounds.Height),
                    new Vector2(waveObj.Bounds.Width, waveObj.Bounds.Height * 1f/2f),
                    direction.Value.X < 0, isWater ? Color.LightBlue : waveColor.Value,
                    isWater));
            }

            /* Spouts */
            IEnumerable<MapObject> spoutObjs = map.FindObjects((layer, obj) => obj.Type == "Spout");
            foreach (MapObject spoutObj in spoutObjs)
            {
                bool isWater = false;
                Color? spoutColor;
                Property colorProperty;
                Debug.Assert(spoutObj.Properties.TryGetValue(COLOR_PROPERTY_NAME, out colorProperty), "Spout has no color.");
                if (colorProperty.RawValue == "Water")
                {
                    spoutColor = Color.LightBlue;
                    isWater = true;
                }
                else
                {
                    spoutColor = ColorHelper.FromString(colorProperty.RawValue);
                }
                Debug.Assert(spoutColor.HasValue, "Invalid color specified for spout.");

                Vector2? spoutDirection;
                Property directionProperty;
                Debug.Assert(spoutObj.Properties.TryGetValue(DIRECTION_PROPERTY_NAME, out directionProperty), "Spout has no direction.");
                spoutDirection = VectorHelper.FromDirectionString(directionProperty.RawValue);
                Debug.Assert(spoutDirection.HasValue, "Invalid direction specified for spout.");

                Add(new SpoutGenerator(new Vector2(spoutObj.Bounds.X, spoutObj.Bounds.Y), spoutDirection.Value, spoutColor.Value, isWater));
            }

            /* Sections */
            IEnumerable<MapObject> sectionObjs = map.FindObjects((layer, obj) => obj.Type == SECTION_OBJECT_NAME);
            foreach (MapObject sectionObj in sectionObjs)
            {
                Property zoomProperty;
                float zoomLevel = -1;
                bool centered = false;

                if (sectionObj.Properties.TryGetValue(ZOOM_PROPERTY_NAME, out zoomProperty))
                    switch (zoomProperty.RawValue)
                    {
                        case NEAR:
                            zoomLevel = NEAR_ZOOM_LEVEL;
                            break;
                        case MEDIUM:
                            zoomLevel = MEDIUM_ZOOM_LEVEL;
                            break;
                        case FAR:
                            zoomLevel = FAR_ZOOM_LEVEL;
                            break;
                        case VERY_FAR:
                            zoomLevel = VERY_FAR_ZOOM_LEVEL;
                            break;
                        case CENTER:
                            centered = true;
                            break;
                        default:
                            throw new InvalidOperationException("Invalid zoom level.");
                    }

                if (centered)
                    sections.Add(new Section(this, sectionObj.Bounds, centered));
                else
                    sections.Add(new Section(this, sectionObj.Bounds, zoomLevel));
            }

            IEnumerable<MapObject> barrierObjs = Map.FindObjects((layer, obj) => obj.Type == "Barrier");
            foreach (MapObject barrierObj in barrierObjs)
            {
                Property colorProperty;
                Color? barrierColor;
                Debug.Assert(barrierObj.Properties.TryGetValue(COLOR_PROPERTY_NAME, out colorProperty), "No color specified for barrier.");
                barrierColor = ColorHelper.FromString(colorProperty.RawValue);
                Debug.Assert(barrierColor.HasValue, "Invalid color specified for barrier.");

                Property directionProperty;
                Vector2? barrierDirection;
                Debug.Assert(barrierObj.Properties.TryGetValue(DIRECTION_PROPERTY_NAME, out directionProperty), "No direction specified for barrier.");
                barrierDirection = VectorHelper.FromDirectionString(directionProperty.RawValue);
                Debug.Assert(barrierDirection.HasValue, "Invalid direction specified for barrier.");

                Vector2 barrierPos = new Vector2(barrierObj.Bounds.X, barrierObj.Bounds.Y);
                Vector2 barrierSize = new Vector2(barrierObj.Bounds.Width, barrierObj.Bounds.Height);
                Add(new Barrier(barrierPos, barrierSize, barrierDirection.Value, barrierColor.Value));

                Vector2 tilespan = GetTilespan(barrierPos, barrierSize);
                Vector2 startPos = GetTileIndexByPixel(barrierPos);
                for (int y = (int)startPos.Y; y < startPos.Y + tilespan.Y; y++)
                    for (int x = (int)startPos.X; x < startPos.X + tilespan.X; x++)
                    {
                        tiles[y, x] = new Tile(new Vector2(x * tilesize.X, y * tilesize.Y), tilesize, TileType.Solid, barrierColor.Value);
                    }
            }
            inkMap = new InkMap(device, width, height);
            miniMap = new MiniMap(this, new Vector2(device.Viewport.Width - MINIMAP_X_OFFSET, 0 + MINIMAP_Y_OFFSET));

            toolbar = new Toolbar(new Vector2(device.Viewport.Width - TOOLBAR_X_OFFSET, 0 + TOOLBAR_Y_OFFSET),
                new Vector2(TOOLBAR_ICONSIZE_X, TOOLBAR_ICONSIZE_Y), new List<Texture2D>
                    {
                        ResourceManager.GetTexture("Misc_Navigation"),
                        ResourceManager.GetTexture("Misc_Reset")
                    }, Orientation.Vertical);
            GameEngine.FadeIn(FadeSpeed.Fast);
        }