コード例 #1
0
        private IEnumerable <TiledMapLayerModel> CreateTileLayerModels(TiledMap map, TiledMapTileLayer tileLayer)
        {
            var layerModels          = new List <TiledMapLayerModel>();
            var staticLayerBuilder   = new TiledMapStaticLayerModelBuilder();
            var animatedLayerBuilder = new TiledMapAnimatedLayerModelBuilder();

            foreach (var tileset in map.Tilesets)
            {
                var firstGlobalIdentifier = map.GetTilesetFirstGlobalIdentifier(tileset);
                var lastGlobalIdentifier  = tileset.TileCount + firstGlobalIdentifier - 1;
                var texture = tileset.Texture;

                foreach (var tile in tileLayer.Tiles.Where(t => firstGlobalIdentifier <= t.GlobalIdentifier && t.GlobalIdentifier <= lastGlobalIdentifier))
                {
                    var tileGid             = tile.GlobalIdentifier;
                    var localTileIdentifier = tileGid - firstGlobalIdentifier;
                    var position            = GetTilePosition(map, tile);
                    var tilesetColumns      = tileset.Columns == 0 ? 1 : tileset.Columns; // fixes a problem (what problem exactly?)
                    var sourceRectangle     = TiledMapHelper.GetTileSourceRectangle(localTileIdentifier, tileset.TileWidth, tileset.TileHeight, tilesetColumns, tileset.Margin, tileset.Spacing);
                    var flipFlags           = tile.Flags;

                    // animated tiles
                    var tilesetTile = tileset.Tiles.FirstOrDefault(x => x.LocalTileIdentifier == localTileIdentifier);

                    if (tilesetTile is TiledMapTilesetAnimatedTile animatedTilesetTile)
                    {
                        animatedLayerBuilder.AddSprite(texture, position, sourceRectangle, flipFlags);
                        animatedLayerBuilder.AnimatedTilesetTiles.Add(animatedTilesetTile);

                        if (animatedLayerBuilder.IsFull)
                        {
                            layerModels.Add(animatedLayerBuilder.Build(_graphicsDevice, texture));
                        }
                    }
                    else
                    {
                        staticLayerBuilder.AddSprite(texture, position, sourceRectangle, flipFlags);

                        if (staticLayerBuilder.IsFull)
                        {
                            layerModels.Add(staticLayerBuilder.Build(_graphicsDevice, texture));
                        }
                    }
                }

                if (staticLayerBuilder.IsBuildable)
                {
                    layerModels.Add(staticLayerBuilder.Build(_graphicsDevice, texture));
                }

                if (animatedLayerBuilder.IsBuildable)
                {
                    layerModels.Add(animatedLayerBuilder.Build(_graphicsDevice, texture));
                }
            }

            return(layerModels);
        }
コード例 #2
0
        private static IEnumerable <TiledMapLayerModelContent> CreateTileLayerModels(TiledMapContent map, string layerName, IEnumerable <TiledMapTile> tiles)
        {
            // the code below builds the geometry (triangles) for every tile
            // for every unique tileset used by a tile in a layer, we are going to end up with a different model (list of vertices and list of indices pair)
            // we also could end up with more models if the map is very large
            // regardless, each model is going to require one draw call to render at runtime

            var modelsByTileset = new Dictionary <TiledMapTilesetContent, List <TiledMapLayerModelContent> >();

            // loop through all the tiles in the proper render order, building the geometry for each tile
            // by processing the tiles in the correct rendering order we ensure the geometry for the tiles will be rendered correctly later using the painter's algorithm
            foreach (var tile in tiles)
            {
                // get the tileset for this tile
                var tileGlobalIdentifier = tile.GlobalIdentifier;
                var tileset = map.Tilesets.FirstOrDefault(x => x.ContainsGlobalIdentifier(tileGlobalIdentifier));
                if (tileset == null)
                {
                    throw new NullReferenceException(
                              $"Could not find tileset for global tile identifier '{tileGlobalIdentifier}'");
                }

                var localTileIdentifier = tileGlobalIdentifier - tileset.FirstGlobalIdentifier;
                Debug.Assert(tileset != null);

                // check if this tile is animated
                var tilesetTile    = tileset.Tiles.FirstOrDefault(x => x.LocalIdentifier == localTileIdentifier);
                var isAnimatedTile = tilesetTile?.Frames != null && tilesetTile.Frames.Count > 0;

                // check if we already have built a list of models for this tileset
                TiledMapLayerModelContent        model;
                List <TiledMapLayerModelContent> models;

                if (modelsByTileset.TryGetValue(tileset, out models))
                {
                    // if we found the list of models for this tileset, try to use the last model added
                    // (assuming the the ones before the last are all full)
                    model = models.FindLast(x => x is TiledMapLayerAnimatedModelContent == isAnimatedTile);
                    // since it is possible that the correct type of model was not added yet we might have to create the correct model now
                    if (model == null)
                    {
                        model = isAnimatedTile
                            ? new TiledMapLayerAnimatedModelContent(layerName, tileset)
                            : new TiledMapLayerModelContent(layerName, tileset);
                        models.Add(model);
                    }
                }
                else
                {
                    // if we have not found the list of models for this tileset, we need to create the list and start a new model of the correct type
                    models = new List <TiledMapLayerModelContent>();
                    model  = isAnimatedTile
                        ? new TiledMapLayerAnimatedModelContent(layerName, tileset)
                        : new TiledMapLayerModelContent(layerName, tileset);
                    models.Add(model);
                    modelsByTileset.Add(tileset, models);
                }

                // check if the current model is full
                if (model.Vertices.Count + TiledMapHelper.VerticesPerTile > TiledMapHelper.MaximumVerticesPerModel)
                {
                    // if the current model is full, we need to start a new one
                    model = isAnimatedTile
                        ? new TiledMapLayerAnimatedModelContent(layerName, tileset)
                        : new TiledMapLayerModelContent(layerName, tileset);
                    models.Add(model);
                }

                // if the tile is animated, record the index of animated tile for the tilset so we can get the correct texture coordinates at runtime
                if (isAnimatedTile)
                {
                    var animatedModel = (TiledMapLayerAnimatedModelContent)model;
                    animatedModel.AddAnimatedTile(tilesetTile);
                }

                // fixes a problem
                if (tileset.Columns == 0)
                {
                    tileset.Columns = 1;
                }

                // build the geometry for the tile
                var position        = GetTilePosition(map, tile);
                var sourceRectangle = TiledMapHelper.GetTileSourceRectangle(localTileIdentifier, tileset.TileWidth,
                                                                            tileset.TileHeight, tileset.Columns, tileset.Margin, tileset.Spacing);
                var flipFlags = tile.Flags;
                model.AddTileIndices();
                model.AddTileVertices(position, sourceRectangle, flipFlags);
            }

            // for each tileset used in this layer
            foreach (var keyValuePair in modelsByTileset)
            {
                var models = keyValuePair.Value;

                // and for each model apart of a tileset
                foreach (var model in models)
                {
                    yield return(model);
                }
            }
        }