Example #1
0
    /// <summary>
    /// Render the level directly without prerendering the layers alot slower than prerendering
    /// </summary>
    /// <param name="level"></param>
    public void RenderLevel(LDtkLevel level)
    {
        Texture2D[] layers = RenderLayers(level);

        for (int i = 0; i < layers.Length; i++)
        {
            SpriteBatch.Draw(layers[i], level.Position.ToVector2(), Color.White);
        }
    }
Example #2
0
 private Texture2D GetTexture(LDtkLevel level, string path)
 {
     if (content == null)
     {
         return(Texture2D.FromFile(graphicsDevice, Path.Combine(level.Parent.RootFolder, path)));
     }
     else
     {
         string file = Path.ChangeExtension(path, null);
         return(content.Load <Texture2D>(file));
     }
 }
Example #3
0
 /// <summary>
 /// Render the prerendered level you created from PrerenderLevel()
 /// </summary>
 /// <param name="level"></param>
 public void RenderPrerenderedLevel(LDtkLevel level)
 {
     if (prerenderedLevels.TryGetValue(level.Identifier, out RenderedLevel prerenderedLevel))
     {
         for (int i = 0; i < prerenderedLevel.layers.Length; i++)
         {
             SpriteBatch.Draw(prerenderedLevel.layers[i], level.Position.ToVector2(), Color.White);
         }
     }
     else
     {
         throw new LevelNotFoundException($"No prerendered level with Identifier {level.Identifier} found.");
     }
 }
Example #4
0
    private Texture2D RenderBackgroundToLayer(LDtkLevel level)
    {
        Texture2D texture = GetTexture(level, level.BgRelPath);

        RenderTarget2D layer = new(graphicsDevice, level.PxWid, level.PxHei, false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents);

        graphicsDevice.SetRenderTarget(layer);
        {
            LevelBackgroundPosition bg = level._BgPos;
            Vector2 pos = bg.TopLeftPx.ToVector2();
            SpriteBatch.Draw(texture, pos, bg.CropRect, Color.White, 0, Vector2.Zero, bg.Scale, SpriteEffects.None, 0);
        }

        graphicsDevice.SetRenderTarget(null);

        return(layer);
    }
Example #5
0
    /// <summary>
    /// Prerender out the level to textures to optimize the rendering process
    /// </summary>
    /// <param name="level">The level to prerender</param>
    /// <exception cref="Exception">The level already has been prerendered</exception>
    public void PrerenderLevel(LDtkLevel level)
    {
        if (prerenderedLevels.ContainsKey(level.Identifier))
        {
            return;
        }

        RenderedLevel renderLevel = new RenderedLevel();

        SpriteBatch.Begin(samplerState: SamplerState.PointClamp);
        {
            renderLevel.layers = RenderLayers(level);
        }

        SpriteBatch.End();

        prerenderedLevels.Add(level.Identifier, renderLevel);
        graphicsDevice.SetRenderTarget(null);
    }
Example #6
0
    private Texture2D[] RenderLayers(LDtkLevel level)
    {
        List <Texture2D> layers = new List <Texture2D>();

        if (level.BgRelPath != null)
        {
            layers.Add(RenderBackgroundToLayer(level));
        }

        // Render Tile, Auto and Int grid layers
        for (int i = level.LayerInstances.Length - 1; i >= 0; i--)
        {
            LayerInstance layer = level.LayerInstances[i];

            if (layer._TilesetRelPath == null)
            {
                continue;
            }

            if (layer._Type == LayerType.Entities)
            {
                continue;
            }

            Texture2D texture = GetTexture(level, layer._TilesetRelPath);

            int            width        = layer._CWid * layer._GridSize;
            int            height       = layer._CHei * layer._GridSize;
            RenderTarget2D renderTarget = new(graphicsDevice, width, height, false, SurfaceFormat.Color, DepthFormat.None, 0, RenderTargetUsage.PreserveContents);

            graphicsDevice.SetRenderTarget(renderTarget);
            layers.Add(renderTarget);

            switch (layer._Type)
            {
            case LayerType.Tiles:
                foreach (TileInstance tile in layer.GridTiles.Where(tile => layer._TilesetDefUid.HasValue))
                {
                    Vector2       position = new(tile.Px.X + layer._PxTotalOffsetX, tile.Px.Y + layer._PxTotalOffsetY);
                    Rectangle     rect     = new(tile.Src.X, tile.Src.Y, layer._GridSize, layer._GridSize);
                    SpriteEffects mirror   = (SpriteEffects)tile.F;
                    SpriteBatch.Draw(texture, position, rect, Color.White, 0, Vector2.Zero, 1f, mirror, 0);
                }

                break;

            case LayerType.AutoLayer:
            case LayerType.IntGrid:
                if (layer.AutoLayerTiles.Length > 0)
                {
                    foreach (TileInstance tile in layer.AutoLayerTiles.Where(tile => layer._TilesetDefUid.HasValue))
                    {
                        Vector2       position = new(tile.Px.X + layer._PxTotalOffsetX, tile.Px.Y + layer._PxTotalOffsetY);
                        Rectangle     rect     = new(tile.Src.X, tile.Src.Y, layer._GridSize, layer._GridSize);
                        SpriteEffects mirror   = (SpriteEffects)tile.F;
                        SpriteBatch.Draw(texture, position, rect, Color.White, 0, Vector2.Zero, 1f, mirror, 0);
                    }
                }

                break;

            case LayerType.Entities:
                break;

            default:
                break;
            }
        }

        return(layers.ToArray());
    }
    private static void ParseCustomFields <T>(T classFields, FieldInstance[] fields, LDtkLevel level)
    {
        for (int i = 0; i < fields.Length; i++)
        {
            FieldInstance fieldInstance = fields[i];
            string        variableName  = fieldInstance._Identifier;

            PropertyInfo variableDef = typeof(T).GetProperty(variableName);

            if (variableDef == null)
            {
                throw new FieldNotFoundException($"Error: Field \"{variableName}\" not found in {typeof(T).FullName}. Maybe you should run ldtkgen again to update the files?");
            }

            // Split any enums
            int enumTypeIndex = fieldInstance._Type.LastIndexOf('.');
            int arrayEndIndex = fieldInstance._Type.LastIndexOf('>');

            string variableType = fieldInstance._Type;

            if (enumTypeIndex != -1)
            {
                variableType = arrayEndIndex != -1
                    ? variableType.Remove(enumTypeIndex, arrayEndIndex - enumTypeIndex)
                    : variableType.Remove(enumTypeIndex, variableType.Length - enumTypeIndex);
            }

            switch (variableType)
            {
            case Field.IntType:
            case Field.BoolType:
            case Field.EnumType:
            case Field.FloatType:
            case Field.StringType:
            case Field.FilePathType:
                if (fieldInstance._Value != null)
                {
                    variableDef.SetValue(classFields, Convert.ChangeType(fieldInstance._Value.ToString(), variableDef.PropertyType));
                }

                break;

            case Field.IntArrayType:
            case Field.BoolArrayType:
            case Field.EnumArrayType:
            case Field.FloatArrayType:
            case Field.StringArrayType:
            case Field.FilePathArrayType:
            case Field.LocalEnumArrayType:
                object primativeArrayValues = JsonSerializer.Deserialize(fieldInstance._Value.ToString(), variableDef.PropertyType, new JsonSerializerOptions()
                {
                    Converters = { new JsonStringEnumConverter() }
                });
                variableDef.SetValue(classFields, Convert.ChangeType(primativeArrayValues, variableDef.PropertyType));
                break;

            case Field.LocalEnumType:
                variableDef.SetValue(classFields, Enum.Parse(variableDef.PropertyType, fieldInstance._Value.ToString()));
                break;

            case Field.ColorType:
                variableDef.SetValue(classFields, ParseStringToColor(fieldInstance._Value.ToString()));
                break;

            // Only Entities can have point fields
            case Field.PointType:
                if (fieldInstance._Value != null)
                {
                    if (variableDef.PropertyType == typeof(Vector2))
                    {
                        Vector2 vector = (Vector2)fieldInstance._Value;
                        variableDef.SetValue(classFields, vector);
                    }
                    else if (variableDef.PropertyType == typeof(Point))
                    {
                        Point point = JsonSerializer.Deserialize <Point>(fieldInstance._Value.ToString(), new JsonSerializerOptions()
                        {
                            Converters = { new CxCyConverter() }
                        });
                        variableDef.SetValue(classFields, point);
                    }
                }
                else
                {
                    if (variableDef.PropertyType == typeof(Vector2))
                    {
                        variableDef.SetValue(classFields, Vector2.Zero);
                    }
                    else if (variableDef.PropertyType == typeof(Point))
                    {
                        variableDef.SetValue(classFields, Point.Zero);
                    }
                }

                break;

            case Field.PointArrayType:
                List <Point> points = JsonSerializer.Deserialize <List <Point> >(fieldInstance._Value.ToString(), new JsonSerializerOptions()
                {
                    Converters = { new CxCyConverter() }
                });

                int gridSize = 0;
                for (int j = 0; j < level.LayerInstances.Length; j++)
                {
                    if (level.LayerInstances[j]._Type == LayerType.Entities)
                    {
                        gridSize = level.LayerInstances[j]._GridSize;
                    }
                }

                for (int j = 0; j < points.Count; j++)
                {
                    points[j]  = new Point(points[j].X * gridSize, points[j].Y * gridSize);
                    points[j] += level.Position;
                    points[j] += new Point(gridSize / 2);
                }

                variableDef.SetValue(classFields, points.ToArray());
                break;

            default:
                throw new FieldNotFoundException("Unknown Variable of type " + fieldInstance._Type);
            }
        }
    }
 /// <summary>
 /// Using Reflections parse the fields in the json/<paramref name="fields"/> into <paramref name="entity"/>
 /// </summary>
 /// <typeparam name="T">Entity Type</typeparam>
 /// <param name="entity">Entity</param>
 /// <param name="fields">LDtk fields to apply to the class</param>
 /// <param name="level"></param>
 /// <exception cref="FieldNotFoundException"></exception>
 public static void ParseCustomEntityFields <T>(T entity, FieldInstance[] fields, LDtkLevel level) where T : new()
 {
     ParseCustomFields(entity, fields, level);
 }
    public static void ParseBaseEntityFields <T>(T entity, EntityInstance entityInstance, LDtkLevel level) where T : new()
    {
        EntityDefinition entityDefinition = level.Parent.GetEntityDefinitionFromUid(entityInstance.DefUid);

        ParseBaseField(entity, "Position", (entityInstance.Px + level.Position).ToVector2());
        ParseBaseField(entity, "Pivot", entityInstance._Pivot);
        ParseBaseField(entity, "Size", new Vector2(entityInstance.Width, entityInstance.Height));
        ParseBaseField(entity, "EditorVisualColor", entityDefinition.Color);

        if (entityInstance._Tile != null)
        {
            EntityInstanceTile tileDefinition = entityInstance._Tile;
            Rectangle          rect           = tileDefinition.SrcRect;
            ParseBaseField(entity, "Tile", rect);
        }
    }