/// <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); } }
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)); } }
/// <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."); } }
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); }
/// <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); }
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); } }