Exemplo n.º 1
0
        public DrawMap(GameState gameState, IOverworld overworld, VirtualResolution virtualResolution, SpriteBatch spriteBatch, IRenderer renderer, IAssetLoader assetLoader, Camera camera, Primitive primitive, GameDate gameDate)
        {
            _random = new Random();

            _overworld         = overworld;
            _virtualResolution = virtualResolution;
            _spriteBatch       = spriteBatch;
            _renderer          = renderer;
            _assetLoader       = assetLoader;
            _camera            = camera;
            _primitive         = primitive;

            _tempTileMap  = _assetLoader.Get <Texture2D>("debug/outmap.png");
            _superTileset = _assetLoader.Get <Texture2D>("debug/supertileset.png");

            _tileMapFilter = new TilemapFilter(_renderer, _spriteBatch,
                                               _assetLoader.Get <Effect>("shaders/tilemap.fx"), 16);
            _tileMapFilter.SetSuperTileset(_superTileset);
            _tileMapFilter.SetTileMapTexture(_tempTileMap);

            _waterReflectionFilter = new WaterReflectionFilter(_renderer, _spriteBatch,
                                                               _assetLoader.Get <Effect>("shaders/water_reflection.fx"));

            _waterFilter = new WaterFilter(_renderer, _spriteBatch, _camera,
                                           _assetLoader.Get <Effect>("shaders/water.fx"),
                                           _assetLoader.Get <Texture2D>("ui/noise.png"),
                                           _assetLoader.Get <Texture2D>("ui/noise2.png"), _virtualResolution);

            _waterDisplacementFilter = new WaterDisplacementFilter(_renderer, _spriteBatch, _virtualResolution,
                                                                   _assetLoader.Get <Effect>("shaders/displace.fx"),
                                                                   _assetLoader.Get <Texture2D>("ui/displacement.png"),
                                                                   _assetLoader.Get <Texture2D>("ui/displacement2.png"));

            _dayNightFilter = new DayNightFilter(_renderer, _spriteBatch, gameDate,
                                                 _assetLoader.Get <Effect>("shaders/average.fx"),
                                                 _assetLoader.Get <Effect>("shaders/color.fx"),
                                                 new List <(float, Texture2D)>()
            {
                (0, assetLoader.Get <Texture2D>("luts/daycycle1.png")),
                (0.1875f, assetLoader.Get <Texture2D>("luts/daycycle1.png")),
                (0.208334f, assetLoader.Get <Texture2D>("luts/daycycle2.png")),
                (0.30208333f, assetLoader.Get <Texture2D>("luts/daycycle3.png")),
                (0.41667f, assetLoader.Get <Texture2D>("luts/daycycle4.png")),
                (0.46f, assetLoader.Get <Texture2D>("luts/daycycle5.png")),
                (0.54f, assetLoader.Get <Texture2D>("luts/daycycle5.png")),
                (0.58333f, assetLoader.Get <Texture2D>("luts/daycycle6.png")),
                (0.6875f, assetLoader.Get <Texture2D>("luts/daycycle7.png")),
                (0.7708333f, assetLoader.Get <Texture2D>("luts/daycycle8.png")),
                (0.82291667f, assetLoader.Get <Texture2D>("luts/daycycle9.png")),
                (0.90625f, assetLoader.Get <Texture2D>("luts/daycycle10.png"))
            });

            CreateRenderTargets();

            _windTrail = new GameObject();
            CAnimation windTrailAnimation;

            _windTrail.Components.Add(new CPosition(Vector2.Zero));
            _windTrail.Components.Add(new CSprite(assetLoader.Get <Texture2D>("ui/windtrail.png"), Vector2.Zero));
            _windTrail.Components.Add(windTrailAnimation = new CAnimation()
            {
                Loop = false, OnComplete = OnComplete
            });
            windTrailAnimation.AddAnimation("effect", new List <AnimationFrame>()
            {
                new AnimationFrame(new Rectangle(0, 0, 512, 54), 0.07f),
                new AnimationFrame(new Rectangle(0, 64, 512, 54), 0.07f),
                new AnimationFrame(new Rectangle(0, 128, 512, 54), 0.07f),
                new AnimationFrame(new Rectangle(0, 192, 512, 54), 0.07f),
                new AnimationFrame(new Rectangle(0, 256, 512, 54), 0.07f),
                new AnimationFrame(new Rectangle(0, 320, 512, 54), 0.07f),
                new AnimationFrame(new Rectangle(0, 384, 512, 54), 0.07f),
                new AnimationFrame(new Rectangle(0, 448, 512, 54), 0.07f),
                new AnimationFrame(new Rectangle(0, 512, 512, 54), 0.07f),
            });
            _windTrail.Components.Add(new CFringeEntity {
                Opacity = 0.15f
            });

            gameState.Stage.GameObjects.Add(_windTrail);
        }
Exemplo n.º 2
0
        public static void CompressLayers(Map map, IAssetLoader assetLoader)
        {
            var outputLayers      = new List <BaseLayer>();
            var maskLayers        = new List <TileLayer>();
            var fringeLayers      = new List <TileLayer>();
            var transparencyCache = new Dictionary <int, bool>();
            var opaqueCache       = new Dictionary <int, bool>();
            var textureCache      = new Dictionary <string, Texture2D>();
            var fringeStart       = false;

            foreach (var layer in map.Layers)
            {
                if (!(layer is TileLayer tileLayer))
                {
                    // todo: figure out something that can process collision shapes
                    // by merging into convex shapes and splitting up accidentally created concave shapes into separate polygons
                    outputLayers.Add(layer);
                    continue;
                }

                if (tileLayer.Name.Equals("FringeStart"))
                {
                    fringeStart = true;
                }

                for (var i = 0; i < tileLayer.Data.Length; i++)
                {
                    var data = tileLayer.Data[i];
                    if (data == 0)
                    {
                        continue;
                    }

                    // check if the tile is wholly transparent, and if it is, skip it
                    if (transparencyCache.ContainsKey(data))
                    {
                        if (transparencyCache[data])
                        {
                            continue;
                        }
                    }
                    else
                    {
                        // we haven't checked this tile yet, so check it.
                        var tileset =
                            map.Tilesets.Single(ts => data >= ts.FirstGid && ts.FirstGid + ts.TileCount > data);

                        var tile        = tileset[data];
                        var tilesetPath = tileset.ImagePath.Replace("../", "");
                        tilesetPath = "tilesets/" + tilesetPath.Substring(tilesetPath.LastIndexOf('/'));

                        if (!textureCache.TryGetValue(tilesetPath, out var tilesetTexture))
                        {
                            tilesetTexture = assetLoader.Get <Texture2D>(tilesetPath);
                            textureCache.Add(tilesetPath, assetLoader.Get <Texture2D>(tilesetPath));
                        }

                        var colorData = GetTextureData(tilesetTexture,
                                                       new Rectangle(tile.Left, tile.Top, tile.Width, tile.Height));

                        var foundOpaque = colorData.All(color => color == Color.Transparent);

                        transparencyCache[data] = foundOpaque;
                        if (foundOpaque)
                        {
                            continue;
                        }
                    }

                    var completelyOpaque = false;
                    var foundLower       = false;

                    // check if the tile is wholly opaque, and if it is, force it below
                    if (opaqueCache.ContainsKey(data))
                    {
                        completelyOpaque = opaqueCache[data];
                    }
                    else
                    {
                        // we haven't checked this tile yet, so check it.
                        var tileset =
                            map.Tilesets.Single(ts => data >= ts.FirstGid && ts.FirstGid + ts.TileCount > data);

                        var tile        = tileset[data];
                        var tilesetPath = tileset.ImagePath.Replace("../", "");
                        tilesetPath = "tilesets/" + tilesetPath.Substring(tilesetPath.LastIndexOf('/'));

                        if (!textureCache.TryGetValue(tilesetPath, out var tilesetTexture))
                        {
                            tilesetTexture = assetLoader.Get <Texture2D>(tilesetPath);
                            textureCache.Add(tilesetPath, assetLoader.Get <Texture2D>(tilesetPath));
                        }

                        var colorData = GetTextureData(tilesetTexture,
                                                       new Rectangle(tile.Left, tile.Top, tile.Width, tile.Height));


                        var foundOpaque = colorData.All(color => color != Color.Transparent);

                        opaqueCache[data] = foundOpaque;
                        completelyOpaque  = foundOpaque;
                    }


                    if (!fringeStart)
                    {
                        if (completelyOpaque)
                        {
                            // force the bottom to the tile and remove everything that comes after it to 0
                            if (maskLayers.Count == 0)
                            {
                                // need to add a layer
                                var newLayer = new TileLayer
                                {
                                    Data      = new int[tileLayer.Data.Length],
                                    Height    = tileLayer.Height,
                                    Width     = tileLayer.Width,
                                    Opacity   = 1,
                                    Visible   = true,
                                    Name      = "M" + (maskLayers.Count + 1),
                                    Encoding  = "csv",
                                    LayerType = LayerType.tilelayer
                                };
                                newLayer.Data[i] = data;
                                maskLayers.Add(newLayer);
                            }
                            else
                            {
                                maskLayers[0].Data[i] = data;
                                for (var e = 1; e < maskLayers.Count; e++)
                                {
                                    maskLayers[e].Data[i] = 0;
                                }
                            }
                        }
                        else
                        {
                            foreach (var currentLayer in maskLayers)
                            {
                                if (currentLayer.Data[i] != 0 && currentLayer.Data[i] != data && !completelyOpaque)
                                {
                                    continue;
                                }

                                // found something that could be compressed
                                currentLayer.Data[i] = data;
                                foundLower           = true;
                                break;
                            }

                            if (foundLower)
                            {
                                continue;
                            }

                            // need to add a layer
                            var newLayer = new TileLayer
                            {
                                Data      = new int[tileLayer.Data.Length],
                                Height    = tileLayer.Height,
                                Width     = tileLayer.Width,
                                Opacity   = 1,
                                Visible   = true,
                                Name      = "M" + (maskLayers.Count + 1),
                                Encoding  = "csv",
                                LayerType = LayerType.tilelayer
                            };
                            newLayer.Data[i] = data;
                            maskLayers.Add(newLayer);
                        }
                    }
                    else
                    {
                        if (completelyOpaque)
                        {
                            // force the bottom to the tile and remove everything that comes after it to 0
                            if (fringeLayers.Count == 0)
                            {
                                // need to add a layer
                                var newLayer = new TileLayer
                                {
                                    Data      = new int[tileLayer.Data.Length],
                                    Height    = tileLayer.Height,
                                    Width     = tileLayer.Width,
                                    Opacity   = 1,
                                    Visible   = true,
                                    Name      = "F" + (fringeLayers.Count + 1),
                                    Encoding  = "csv",
                                    LayerType = LayerType.tilelayer
                                };
                                newLayer.Data[i] = data;
                                fringeLayers.Add(newLayer);
                            }
                            else
                            {
                                fringeLayers[0].Data[i] = data;
                                for (var e = 1; e < fringeLayers.Count; e++)
                                {
                                    fringeLayers[e].Data[i] = 0;
                                }
                            }

                            // removing everything in mask at this point because it's being occluded anyway
                            foreach (var p in maskLayers)
                            {
                                p.Data[i] = 0;
                            }
                        }
                        else
                        {
                            foreach (var currentLayer in fringeLayers)
                            {
                                if (currentLayer.Data[i] != 0 && currentLayer.Data[i] != data)
                                {
                                    continue;
                                }

                                // found something that could be compressed
                                currentLayer.Data[i] = data;
                                foundLower           = true;
                                break;
                            }

                            if (foundLower)
                            {
                                continue;
                            }

                            // need to add a layer
                            var newLayer = new TileLayer
                            {
                                Data      = new int[tileLayer.Data.Length],
                                Height    = tileLayer.Height,
                                Width     = tileLayer.Width,
                                Opacity   = 1,
                                Visible   = true,
                                Name      = "F" + (fringeLayers.Count + 1),
                                Encoding  = "csv",
                                LayerType = LayerType.tilelayer
                            };
                            newLayer.Data[i] = data;
                            fringeLayers.Add(newLayer);
                        }
                    }
                }
            }

            // remove layers that might've been made completely blank in the occlusion steps
            maskLayers.RemoveAll(layers => layers.Data.All(data => data == 0));
            fringeLayers.RemoveAll(layers => layers.Data.All(data => data == 0));

            outputLayers.AddRange(maskLayers);
            outputLayers.AddRange(fringeLayers);
            map.Layers = outputLayers.ToArray();
        }
Exemplo n.º 3
0
        private void ParseTiles(Map map)
        {
            var isMask       = true;
            var tilesetCache = new Dictionary <int, ITileset>();

            map.Layers
            .OfType <TileLayer>()
            .ForEach(layer =>
            {
                if (layer.Name.Equals("FringeStart"))
                {
                    isMask = false;
                }

                for (int y = 0, i = 0; y < layer.Height; y++)
                {
                    for (var x = 0; x < layer.Width; x++, i++)
                    {
                        var gid = layer.Data[i];
                        if (gid == 0)
                        {
                            continue;
                        }

                        if (!tilesetCache.TryGetValue(gid, out var tileset))
                        {
                            tileset = map.Tilesets.Single(ts =>
                                                          gid >= ts.FirstGid && ts.FirstGid + ts.TileCount > gid);
                            tilesetCache.Add(gid, tileset);
                        }

                        var tile = tileset[gid];

                        var posX = map.XOffset + x * map.CellWidth + layer.X;
                        var posY = map.YOffset + y * map.CellHeight + layer.Y;

                        var relativeId = gid - tileset.FirstGid;
                        if (tileset.TileProperties.TryGetValue(relativeId, out var item))
                        {
                            var values = item.Values.Select(i => i);
                            foreach (var value in values)
                            {
                                var split = value.Split('|');
                                switch (split[0])
                                {
                                case "emitter":
                                    var px     = (int)float.Parse(split[2]);
                                    var py     = (int)float.Parse(split[3]);
                                    var width  = (int)float.Parse(split[4]);
                                    var height = (int)float.Parse(split[5]);
                                    var bounds = new Rectangle(tile.Left + px, tile.Top + py, width, height);

                                    if (!new Rectangle(tile.Left, tile.Top, tile.Width, tile.Height)
                                        .Contains(bounds))
                                    {
                                        continue;
                                    }

                                    var ty      = posY - (tile.Height) + 16 + py;
                                    var boundsT = new Rectangle(posX + px, ty, width, height);
                                    var boundsF = new RectangleF(posX + px, ty, width, height);

                                    switch (split[1])
                                    {
                                    case "leaf":
                                        // todo: use isMask to determine
                                        _maskEmitters.Add(new Emitter <Leaf>(_random, 2,
                                                                             _assetLoader.Get <Texture2D>("particles/leaf.png"),
                                                                             boundsT), boundsF);

                                        _fringeEmitters.Add(new Emitter <Leaf>(_random, 1,
                                                                               _assetLoader.Get <Texture2D>("particles/leaf.png"),
                                                                               boundsT), boundsF);
                                        break;

                                    default:
                                        break;
                                    }

                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                    }
                }
            });
        }