/// <summary> /// Parse a level created with Tiled and the objects within. /// </summary> /// <param name="xml">XML representation of level as written by Tiled editor.</param> /// <returns>Level descriptor and descriptors of objects within the level.</returns> private static Level ParseLevel(string xml) { XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); LevelProperties level = ParseLevelHeader(doc); ReadOnlyCollection <LevelObject> levelObjects = ParseLevelTiles(doc, level); return(new Level(level, levelObjects)); }
/// <summary> /// Constructs a correct type of marker for the level. /// </summary> /// <param name="level">The level GameObject to assign the Marker to.</param> /// <param name="properties">The <see cref="LevelProperties"/> object describing the level.</param> /// <returns>The constructed marker.</returns> private Marker ConstructMarker(GameObject level, LevelProperties properties) { Vector3 position = new Vector3( (this.BoardSize.x - properties.Width) / 2, 0, -(this.BoardSize.y - properties.Height) / 2); Debug.Log("Level position: " + position); GameObject levelMarker = new GameObject("LevelMarker"); this.AddBoard(levelMarker); if (GameObject.Find("MetaWorld") == null) { RemoteMarker remoteMarker = levelMarker.AddComponent <RemoteMarker>(); remoteMarker.Id = LevelMarkerID; remoteMarker.ScaleFactor = 1f; GameObject.Find("RemoteController") .GetComponent <RemoteMarkerHolder>() .AddMarker(remoteMarker as RemoteMarker); } else { LocalMarker localMarker = levelMarker.AddComponent <LocalMarker>(); localMarker.Id = LevelMarkerID; GameObject.Find("MetaWorld") .GetComponent <LocalMarkerHolder>() .AddMarker(localMarker as LocalMarker); } level.transform.parent = levelMarker.transform; level.transform.localPosition = position; Marker marker = levelMarker.GetComponent <Marker>(); // Simulate a PositionUpdate from the server. PositionUpdate update = new PositionUpdate(UpdateType.UpdatePosition, Vector3.zero, 0, LevelMarkerID); marker.RemotePosition = new MarkerPosition(update); marker.RemotePosition.Scale = Vector3.one; return(marker); }
/// <summary> /// Read level info from XML exported by Tiled. /// </summary> /// <param name="levelDoc">XML document of level.</param> /// <returns>Info about level.</returns> private static LevelProperties ParseLevelHeader(XmlDocument levelDoc) { LevelProperties properties = new LevelProperties(); // Find nodes containing relevant attributes var mapNode = levelDoc.SelectSingleNode("map"); var imageNode = levelDoc.SelectSingleNode("//image"); var tilesetNode = levelDoc.SelectSingleNode("//tileset"); // Read data from them properties.Width = int.Parse(mapNode.Attributes["width"].Value, CultureInfo.InvariantCulture); properties.Height = int.Parse(mapNode.Attributes["height"].Value, CultureInfo.InvariantCulture); properties.TileWidth = int.Parse(tilesetNode.Attributes["tilewidth"].Value, CultureInfo.InvariantCulture); properties.TileHeight = int.Parse(tilesetNode.Attributes["tileheight"].Value, CultureInfo.InvariantCulture); properties.HorizontalTiles = int.Parse(imageNode.Attributes["width"].Value, CultureInfo.InvariantCulture) / properties.TileWidth; properties.VerticalTiles = int.Parse(imageNode.Attributes["height"].Value, CultureInfo.InvariantCulture) / properties.TileHeight; return(properties); }
/// <summary> /// Constructs the game objects from objects within a level. /// </summary> /// <param name="level">Level descriptor.</param> /// <param name="levelObjects">List of level objects.</param> /// <returns>Parent GameObject that represents level.</returns> private GameObject ConstructLevel(LevelProperties level, ReadOnlyCollection <LevelObject> levelObjects) { GameObject parent = new GameObject("Level"); // Instantiate prefab for every level object foreach (LevelObject obj in levelObjects) { try { GameObject instance = InstantiateLevelObject(obj, this.objectPrefabs); instance.transform.parent = parent.transform; } catch (KeyNotFoundException) { Debug.LogError("No prefab for " + obj.Type); } } LinkPortals(levelObjects); Marker marker = this.ConstructMarker(parent, level); return(marker.gameObject); }
/// <summary> /// Initializes a new instance of the <see cref="Level"/> class. /// </summary> /// <param name="properties">Level properties.</param> /// <param name="objects">Objects within level.</param> public Level(LevelProperties properties, ReadOnlyCollection <LevelObject> objects) { this.Properties = properties; this.Objects = objects; }
/// <summary> /// Load objects from tiles in level exported to XML. /// </summary> /// <param name="levelDoc">XML document of level.</param> /// <param name="level">Level descriptor returned by ParseLevelHeader.</param> /// <returns>List of objects placed within level.</returns> private static ReadOnlyCollection <LevelObject> ParseLevelTiles(XmlDocument levelDoc, LevelProperties level) { int x = 0; int y = 0; var levelObjects = new List <LevelObject>(); foreach (XmlNode tileNode in levelDoc.SelectNodes("//tile")) { int gid = int.Parse(tileNode.Attributes["gid"].Value, CultureInfo.InvariantCulture); // Bug in Tiled where it sometimes outputs tiles with gid 1 as 0 gid = Math.Max(1, gid); // Determine rotation of object int rotation = ((gid - 1) / level.HorizontalTiles) * 45; // Determine type of object int rawType = (gid - 1) % level.HorizontalTiles; TileType type = (TileType)rawType; // Determine position of object in world coordinates Vector2 pos = new Vector2(x, y); if (type != TileType.Nothing) { levelObjects.Add(new LevelObject(type, pos, rotation)); } // UpdatePosition X, Y position if (x + 1 == level.Width) { y++; } x = (x + 1) % level.Width; } return(levelObjects.AsReadOnly()); }