private static void ApplyPropertiesTo(PositionedObject entity, MapDrawableBatch layer, int tileIndex, List <NamedValue> propertiesToAssign) { int vertexIndex = tileIndex * 4; var dimension = (layer.Vertices[vertexIndex + 1].Position - layer.Vertices[vertexIndex].Position).Length(); float dimensionHalf = dimension / 2.0f; float left; float bottom; layer.GetBottomLeftWorldCoordinateForOrderedTile(tileIndex, out left, out bottom); Microsoft.Xna.Framework.Vector3 position = new Microsoft.Xna.Framework.Vector3(left, bottom, 0); var bottomRight = layer.Vertices[tileIndex * 4 + 1].Position; float xDifference = bottomRight.X - left; float yDifference = bottomRight.Y - bottom; if (yDifference != 0 || xDifference < 0) { float angle = (float)System.Math.Atan2(yDifference, xDifference); entity.RotationZ = angle; } position += entity.RotationMatrix.Right * dimensionHalf; position += entity.RotationMatrix.Up * dimensionHalf; position += layer.Position; ApplyPropertiesTo(entity, propertiesToAssign, position); }
private static void AddCollisionFromLayerInternal(TileShapeCollection tileShapeCollection, Func <List <TMXGlueLib.DataTypes.NamedValue>, bool> predicate, Dictionary <string, List <TMXGlueLib.DataTypes.NamedValue> > properties, float dimension, float dimensionHalf, Dictionary <int, List <int> > rectangleIndexes, MapDrawableBatch layer) { foreach (var kvp in properties) { string name = kvp.Key; var namedValues = kvp.Value; if (predicate(namedValues)) { var dictionary = layer.NamedTileOrderedIndexes; if (dictionary.ContainsKey(name)) { var indexList = dictionary[name]; foreach (var index in indexList) { float left; float bottom; layer.GetBottomLeftWorldCoordinateForOrderedTile(index, out left, out bottom); var centerX = left + dimensionHalf; var centerY = bottom + dimensionHalf; int key; int value; if (tileShapeCollection.SortAxis == Axis.X) { key = (int)(centerX / dimension); value = (int)(centerY / dimension); } else if (tileShapeCollection.SortAxis == Axis.Y) { key = (int)(centerY / dimension); value = (int)(centerX / dimension); } else { throw new NotImplementedException("Cannot add tile collision on z-sorted shape collections"); } List <int> listToAddTo = null; if (rectangleIndexes.ContainsKey(key) == false) { listToAddTo = new List <int>(); rectangleIndexes.Add(key, listToAddTo); } else { listToAddTo = rectangleIndexes[key]; } listToAddTo.Add(value); } } } } }
public static void AddCollisionFrom(this TileShapeCollection tileShapeCollection, MapDrawableBatch layer, LayeredTileMap layeredTileMap, Func <List <TMXGlueLib.DataTypes.NamedValue>, bool> predicate) { var properties = layeredTileMap.TileProperties; foreach (var kvp in properties) { string name = kvp.Key; var namedValues = kvp.Value; if (predicate(namedValues)) { float dimension = layeredTileMap.WidthPerTile.Value; float dimensionHalf = dimension / 2.0f; tileShapeCollection.GridSize = dimension; var dictionary = layer.NamedTileOrderedIndexes; if (dictionary.ContainsKey(name)) { var indexList = dictionary[name]; foreach (var index in indexList) { float left; float bottom; layer.GetBottomLeftWorldCoordinateForOrderedTile(index, out left, out bottom); var centerX = left + dimensionHalf; var centerY = bottom + dimensionHalf; tileShapeCollection.AddCollisionAtWorld(centerX, centerY); } } } } }
private static void CreateEntitiesFrom(List <string> entitiesToRemove, MapDrawableBatch layer, Dictionary <string, List <NamedValue> > propertiesDictionary, float tileSize, InstantiationRestrictions restrictions = null) { var flatRedBallLayer = SpriteManager.Layers.FirstOrDefault(item => item.Batches.Contains(layer)); var dictionary = layer.NamedTileOrderedIndexes; // layer needs its position updated: layer.ForceUpdateDependencies(); foreach (var propertyList in propertiesDictionary.Values) { var property = propertyList.FirstOrDefault(item2 => item2.Name == "EntityToCreate" || item2.Name == "Type"); if (!string.IsNullOrEmpty(property.Name)) { var tileName = propertyList.FirstOrDefault(item => item.Name.ToLowerInvariant() == "name").Value as string; var entityType = property.Value as string; var shouldCreateEntityType = !string.IsNullOrEmpty(entityType) && dictionary.ContainsKey(tileName); if (shouldCreateEntityType && restrictions?.InclusiveList != null) { shouldCreateEntityType = restrictions.InclusiveList.Contains(entityType); } if (shouldCreateEntityType) { IEntityFactory factory = GetFactory(entityType); if (factory == null && CreationFunction == null) { bool isEntity = typesInThisAssembly.Any(item => item.Name.Contains($".Entities.") && item.Name.EndsWith(entityType)); if (isEntity) { string message = $"The factory for entity {entityType} could not be found. To create instances of this entity, " + "set its 'CreatedByOtherEntities' property to true in Glue."; throw new Exception(message); } } else { var createdEntityOfThisType = false; var indexList = dictionary[tileName]; foreach (var tileIndex in indexList) { var shouldCreate = true; var bounds = restrictions?.Bounds; if (bounds != null) { layer.GetBottomLeftWorldCoordinateForOrderedTile(tileIndex, out float x, out float y); x += tileSize / 2.0f; y += tileSize / 2.0f; shouldCreate = bounds.IsPointInside(x, y); } if (shouldCreate) { PositionedObject entity = null; if (factory != null) { entity = factory.CreateNew(flatRedBallLayer) as PositionedObject; } else if (CreationFunction != null) { entity = CreationFunction(entityType); // todo - need to support moving to layer } if (entity != null) { ApplyPropertiesTo(entity, layer, tileIndex, propertyList); createdEntityOfThisType = true; } } } if (createdEntityOfThisType) { entitiesToRemove.Add(entityType); } } } } } }
private static void CreateEntitiesFrom(List<string> entitiesToRemove, MapDrawableBatch layer, IEnumerable<TileMapInfo> tileMapInfos) { float dimension = float.NaN; float dimensionHalf = 0; var dictionary = layer.NamedTileOrderedIndexes; foreach (var info in tileMapInfos) { if (!string.IsNullOrEmpty(info.EntityToCreate) && dictionary.ContainsKey(info.Name)) { #if WINDOWS_8 var assembly = typeof(TileEntityInstantiator).GetTypeInfo().Assembly; var types = assembly.DefinedTypes; var filteredTypes = types.Where(t => t.ImplementedInterfaces.Contains(typeof(IEntityFactory)) && t.DeclaredConstructors.Any(c=>c.GetParameters().Count() == 0)); #else var assembly = Assembly.GetExecutingAssembly(); var types = assembly.GetTypes(); var filteredTypes = types.Where(t => t.GetInterfaces().Contains(typeof(IEntityFactory)) && t.GetConstructor(Type.EmptyTypes) != null); #endif var factories = filteredTypes .Select( t => { #if WINDOWS_8 var propertyInfo = t.DeclaredProperties.First(item => item.Name == "Self"); #else var propertyInfo = t.GetProperty("Self"); #endif var value = propertyInfo.GetValue(null, null); return value as IEntityFactory; }).ToList(); foreach (var factory in factories) { var type = factory.GetType(); var methodInfo = type.GetMethod("CreateNew", new[] { typeof(Layer) }); var returntypeString = methodInfo.ReturnType.Name; if (info.EntityToCreate.EndsWith("\\" + returntypeString)) { entitiesToRemove.Add(info.EntityToCreate); var indexList = dictionary[info.Name]; foreach (var tileIndex in indexList) { float left; float bottom; layer.GetBottomLeftWorldCoordinateForOrderedTile(tileIndex, out left, out bottom); if (float.IsNaN(dimension)) { int vertexIndex = tileIndex * 4; dimension = layer.Vertices[vertexIndex + 1].Position.X - layer.Vertices[vertexIndex].Position.X; dimensionHalf = dimension / 2.0f; } var entity = factory.CreateNew() as PositionedObject; if (entity != null) { entity.X = left + dimensionHalf; entity.Y = bottom + dimensionHalf; } } } } } } }