diff options
author | chai <215380520@qq.com> | 2024-06-03 10:15:45 +0800 |
---|---|---|
committer | chai <215380520@qq.com> | 2024-06-03 10:15:45 +0800 |
commit | acea7b2e728787a0d83bbf83c8c1f042d2c32e7e (patch) | |
tree | 0bfec05c1ca2d71be2c337bcd110a0421f19318b /Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/TiledMapReader.cs | |
parent | 88febcb02bf127d961c6471d9e846c0e1315f5c3 (diff) |
+ plugins project
Diffstat (limited to 'Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/TiledMapReader.cs')
-rw-r--r-- | Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/TiledMapReader.cs | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/TiledMapReader.cs b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/TiledMapReader.cs new file mode 100644 index 0000000..bd49655 --- /dev/null +++ b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/TiledMapReader.cs @@ -0,0 +1,229 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using MonoGame.Extended.Content; + +namespace MonoGame.Extended.Tiled +{ + public class TiledMapReader : ContentTypeReader<TiledMap> + { + protected override TiledMap Read(ContentReader reader, TiledMap existingInstance) + { + if (existingInstance != null) + return existingInstance; + + var map = ReadTiledMap(reader); + reader.ReadTiledMapProperties(map.Properties); + ReadTilesets(reader, map); + ReadLayers(reader, map); + return map; + } + + private static TiledMap ReadTiledMap(ContentReader reader) + { + var name = reader.AssetName; + var type = reader.ReadString(); + var width = reader.ReadInt32(); + var height = reader.ReadInt32(); + var tileWidth = reader.ReadInt32(); + var tileHeight = reader.ReadInt32(); + var backgroundColor = reader.ReadColor(); + var renderOrder = (TiledMapTileDrawOrder)reader.ReadByte(); + var orientation = (TiledMapOrientation)reader.ReadByte(); + + return new TiledMap(name, type, width, height, tileWidth, tileHeight, renderOrder, orientation, backgroundColor); + } + + private static void ReadTilesets(ContentReader reader, TiledMap map) + { + var tilesetCount = reader.ReadInt32(); + + for (var i = 0; i < tilesetCount; i++) + { + var firstGlobalIdentifier = reader.ReadInt32(); + var tileset = ReadTileset(reader, map); + map.AddTileset(tileset, firstGlobalIdentifier); + } + } + + private static TiledMapTileset ReadTileset(ContentReader reader, TiledMap map) + { + var external = reader.ReadBoolean(); + var tileset = external ? reader.ReadExternalReference<TiledMapTileset>() : TiledMapTilesetReader.ReadTileset(reader); + + return tileset; + } + + private static void ReadLayers(ContentReader reader, TiledMap map) + { + foreach (var layer in ReadGroup(reader, map)) + map.AddLayer(layer); + } + private static List<TiledMapLayer> ReadGroup(ContentReader reader, TiledMap map) + { + var layerCount = reader.ReadInt32(); + var value = new List<TiledMapLayer>(layerCount); + + for (var i = 0; i < layerCount; i++) + value.Add(ReadLayer(reader, map)); + + return value; + } + + private static TiledMapLayer ReadLayer(ContentReader reader, TiledMap map) + { + var layerType = (TiledMapLayerType)reader.ReadByte(); + var name = reader.ReadString(); + var type = reader.ReadString(); + var isVisible = reader.ReadBoolean(); + var opacity = reader.ReadSingle(); + var offsetX = reader.ReadSingle(); + var offsetY = reader.ReadSingle(); + var offset = new Vector2(offsetX, offsetY); + var parallaxX = reader.ReadSingle(); + var parallaxY = reader.ReadSingle(); + var parallaxFactor = new Vector2(parallaxX, parallaxY); + var properties = new TiledMapProperties(); + + reader.ReadTiledMapProperties(properties); + + TiledMapLayer layer; + + switch (layerType) + { + case TiledMapLayerType.ImageLayer: + layer = ReadImageLayer(reader, name, type, offset, parallaxFactor, opacity, isVisible); + break; + case TiledMapLayerType.TileLayer: + layer = ReadTileLayer(reader, name, type, offset, parallaxFactor, opacity, isVisible, map); + break; + case TiledMapLayerType.ObjectLayer: + layer = ReadObjectLayer(reader, name, type, offset, parallaxFactor, opacity, isVisible, map); + break; + case TiledMapLayerType.GroupLayer: + layer = new TiledMapGroupLayer(name, type, ReadGroup(reader, map), offset, parallaxFactor, opacity, isVisible); + break; + default: + throw new ArgumentOutOfRangeException(); + } + + foreach (var property in properties) + layer.Properties.Add(property.Key, property.Value); + + return layer; + } + + private static TiledMapLayer ReadObjectLayer(ContentReader reader, string name, string type, Vector2 offset, Vector2 parallaxFactor, float opacity, bool isVisible, TiledMap map) + { + var color = reader.ReadColor(); + var drawOrder = (TiledMapObjectDrawOrder)reader.ReadByte(); + var objectCount = reader.ReadInt32(); + var objects = new TiledMapObject[objectCount]; + + for (var i = 0; i < objectCount; i++) + objects[i] = ReadTiledMapObject(reader, map); + + return new TiledMapObjectLayer(name, type, objects, color, drawOrder, offset, parallaxFactor, opacity, isVisible); + } + + private static TiledMapObject ReadTiledMapObject(ContentReader reader, TiledMap map) + { + var objectType = (TiledMapObjectType)reader.ReadByte(); + var identifier = reader.ReadInt32(); + var name = reader.ReadString(); + var type = reader.ReadString(); + var position = new Vector2(reader.ReadSingle(), reader.ReadSingle()); + var width = reader.ReadSingle(); + var height = reader.ReadSingle(); + var size = new Size2(width, height); + var rotation = reader.ReadSingle(); + var isVisible = reader.ReadBoolean(); + var properties = new TiledMapProperties(); + const float opacity = 1.0f; + + reader.ReadTiledMapProperties(properties); + + TiledMapObject mapObject; + + switch (objectType) + { + case TiledMapObjectType.Rectangle: + mapObject = new TiledMapRectangleObject(identifier, name, size, position, rotation, opacity, isVisible, type); + break; + case TiledMapObjectType.Tile: + var globalTileIdentifierWithFlags = reader.ReadUInt32(); + var tile = new TiledMapTile(globalTileIdentifierWithFlags, (ushort)position.X, (ushort)position.Y); + var tileset = map.GetTilesetByTileGlobalIdentifier(tile.GlobalIdentifier); + var localTileIdentifier = tile.GlobalIdentifier - map.GetTilesetFirstGlobalIdentifier(tileset); + var tilesetTile = tileset.Tiles.FirstOrDefault(x => x.LocalTileIdentifier == localTileIdentifier); + mapObject = new TiledMapTileObject(identifier, name, tileset, tilesetTile, size, position, rotation, opacity, isVisible, type); + break; + case TiledMapObjectType.Ellipse: + mapObject = new TiledMapEllipseObject(identifier, name, size, position, rotation, opacity, isVisible); + break; + case TiledMapObjectType.Polygon: + mapObject = new TiledMapPolygonObject(identifier, name, ReadPoints(reader), size, position, rotation, opacity, isVisible, type); + break; + case TiledMapObjectType.Polyline: + mapObject = new TiledMapPolylineObject(identifier, name, ReadPoints(reader), size, position, rotation, opacity, isVisible, type); + break; + default: + throw new ArgumentOutOfRangeException(); + } + + foreach (var property in properties) + mapObject.Properties.Add(property.Key, property.Value); + + return mapObject; + } + + private static Point2[] ReadPoints(ContentReader reader) + { + var pointCount = reader.ReadInt32(); + var points = new Point2[pointCount]; + + for (var i = 0; i < pointCount; i++) + { + var x = reader.ReadSingle(); + var y = reader.ReadSingle(); + points[i] = new Point2(x, y); + } + + return points; + } + + private static TiledMapImageLayer ReadImageLayer(ContentReader reader, string name, string type, Vector2 offset, Vector2 parallaxFactor, float opacity, bool isVisible) + { + var texture = reader.ReadExternalReference<Texture2D>(); + var x = reader.ReadSingle(); + var y = reader.ReadSingle(); + var position = new Vector2(x, y); + return new TiledMapImageLayer(name, type, texture, position, offset, parallaxFactor, opacity, isVisible); + } + + private static TiledMapTileLayer ReadTileLayer(ContentReader reader, string name, string type, Vector2 offset, Vector2 parallaxFactor, float opacity, bool isVisible, TiledMap map) + { + var width = reader.ReadInt32(); + var height = reader.ReadInt32(); + var tileWidth = map.TileWidth; + var tileHeight = map.TileHeight; + + var tileCount = reader.ReadInt32(); + var layer = new TiledMapTileLayer(name, type, width, height, tileWidth, tileHeight, offset, parallaxFactor, opacity, isVisible); + + for (var i = 0; i < tileCount; i++) + { + var globalTileIdentifierWithFlags = reader.ReadUInt32(); + var x = reader.ReadUInt16(); + var y = reader.ReadUInt16(); + + layer.Tiles[x + y * width] = new TiledMapTile(globalTileIdentifierWithFlags, x, y); + } + + return layer; + } + } +} |