From 8048cf7691030bdd0b66d14392700856efc7e213 Mon Sep 17 00:00:00 2001 From: Victor Chelaru Date: Sat, 23 Feb 2019 21:03:52 -0700 Subject: [PATCH] [Glue + Tiled] - Foldered entities can be instantiated in Tiled maps using either forward or back slashes. [Autopmated Test] - Added test for instantiating entities. --- .../TileEntityInstantiator.cs | 4 +- .../EntityFolder/TiledEntityInFolder.cs | 45 ++++++++++++ .../GlueTestProject/GlueTestProject.csproj | 5 ++ .../GlueTestProject/GlueTestProject.glux | 66 +++++++++++++++++ .../GlueTestProject/Screens/TmxScreen.cs | 14 ++++ .../GlueTestProject/Setup/CameraSetup.cs | 13 +++- .../TileEntities/TileEntityInstantiator.cs | 4 +- .../TileGraphics/LayeredTileMap.cs | 71 +++++++------------ .../TileGraphics/MapDrawableBatch.cs | 14 ++-- .../GlueTestProjectContent.contentproj | 8 +++ .../Screens/TmxScreen/TilesetWithEntities.tsx | 6 ++ .../Screens/TmxScreen/TmxWithEntities.tmx | 9 +++ 12 files changed, 201 insertions(+), 58 deletions(-) create mode 100644 Tests/GlueTestProject/GlueTestProject/GlueTestProject/Entities/EntityFolder/TiledEntityInFolder.cs create mode 100644 Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/Screens/TmxScreen/TilesetWithEntities.tsx create mode 100644 Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/Screens/TmxScreen/TmxWithEntities.tmx diff --git a/FRBDK/Glue/TileGraphicsPlugin/TileGraphicsPlugin/TileEntityInstantiator.cs b/FRBDK/Glue/TileGraphicsPlugin/TileGraphicsPlugin/TileEntityInstantiator.cs index 25251c545..1118215ae 100644 --- a/FRBDK/Glue/TileGraphicsPlugin/TileGraphicsPlugin/TileEntityInstantiator.cs +++ b/FRBDK/Glue/TileGraphicsPlugin/TileGraphicsPlugin/TileEntityInstantiator.cs @@ -525,7 +525,9 @@ private static IEntityFactory GetFactory(string entityType) var methodInfo = type.GetMethod("CreateNew", new[] { typeof(Layer), typeof(float), typeof(float) }); var returntypeString = methodInfo.ReturnType.Name; - return entityType == returntypeString || entityType.EndsWith("\\" + returntypeString); + return entityType == returntypeString || + entityType.EndsWith("\\" + returntypeString) || + entityType.EndsWith("/" + returntypeString); }); return factory; } diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Entities/EntityFolder/TiledEntityInFolder.cs b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Entities/EntityFolder/TiledEntityInFolder.cs new file mode 100644 index 000000000..390b69737 --- /dev/null +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Entities/EntityFolder/TiledEntityInFolder.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FlatRedBall; +using FlatRedBall.Input; +using FlatRedBall.Instructions; +using FlatRedBall.AI.Pathfinding; +using FlatRedBall.Graphics.Animation; +using FlatRedBall.Graphics.Particle; +using FlatRedBall.Math.Geometry; + +namespace GlueTestProject.Entities.EntityFolder +{ + public partial class TiledEntityInFolder + { + /// + /// Initialization logic which is execute only one time for this Entity (unless the Entity is pooled). + /// This method is called when the Entity is added to managers. Entities which are instantiated but not + /// added to managers will not have this method called. + /// + private void CustomInitialize() + { + + + } + + private void CustomActivity() + { + + + } + + private void CustomDestroy() + { + + + } + + private static void CustomLoadStaticContent(string contentManagerName) + { + + + } + } +} diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/GlueTestProject.csproj b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/GlueTestProject.csproj index 77f244dd5..83e59c163 100644 --- a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/GlueTestProject.csproj +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/GlueTestProject.csproj @@ -396,6 +396,10 @@ StateEntityInFolder.cs + + + TiledEntityInFolder.cs + EntityForTestPlugin.cs @@ -842,6 +846,7 @@ + diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/GlueTestProject.glux b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/GlueTestProject.glux index cdb95d1f7..d58da7e6c 100644 --- a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/GlueTestProject.glux +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/GlueTestProject.glux @@ -3724,6 +3724,15 @@ true true + + FlatRedBallType + PositionedObjectList<T> + Entities\EntityFolder\TiledEntityInFolder + TiledEntityInFolderList + true + true + true + @@ -3812,6 +3821,12 @@ FlatRedBall.TileGraphics.LayeredTileMap + + Screens/TmxScreen/TmxWithEntities.tmx + true + FlatRedBall.TileGraphics.LayeredTileMap + + @@ -3843,6 +3858,15 @@ true true + + FlatRedBallType + PositionedObjectList<T> + Entities\EntityFolder\TiledEntityInFolder + TiledEntityInFolderList + true + true + true + @@ -8124,6 +8148,48 @@ Entities\EntityFolder\StateEntityInFolder true + + + GLUE + + GLUE + + + + + Type + float + + + X + float + + + + + Type + float + + + Y + float + + + + + Type + float + + + Z + float + + + false + Entities\EntityFolder\TiledEntityInFolder + true + true + diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Screens/TmxScreen.cs b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Screens/TmxScreen.cs index 0d5cf82e4..6cff314b6 100644 --- a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Screens/TmxScreen.cs +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Screens/TmxScreen.cs @@ -13,6 +13,8 @@ using Cursor = FlatRedBall.Gui.Cursor; using GuiManager = FlatRedBall.Gui.GuiManager; using FlatRedBall.Localization; +using GlueTestProject.TestFramework; +using FlatRedBall.TileEntities; #if FRB_XNA || SILVERLIGHT using Keys = Microsoft.Xna.Framework.Input.Keys; @@ -62,6 +64,8 @@ void CustomInitialize() TestTileSizeOnMapWithObjects(); + TestEntitiesInFolders(); + // Make the shapes visible, to make sure that they get removed when the screen is destroyed: foreach(var shapeCollection in TmxWithShapes.ShapeCollections) { @@ -70,6 +74,16 @@ void CustomInitialize() } } + private void TestEntitiesInFolders() + { + this.TiledEntityInFolderList.Count + .ShouldBe(0, "because entities haven't yet been created"); + TileEntityInstantiator.CreateEntitiesFrom(TmxWithEntities); + + this.TiledEntityInFolderList.Count + .ShouldBe(2, "because there are 2 tile instances creating this entity, one with a forward slash, one with a back slash"); + } + private void TestTileSizeOnMapWithObjects() { var expectedWidth = 32 * 16; diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Setup/CameraSetup.cs b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Setup/CameraSetup.cs index 456edd3f2..0c9d5ff2f 100644 --- a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Setup/CameraSetup.cs +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/Setup/CameraSetup.cs @@ -84,7 +84,14 @@ internal static void ResetWindow () } else { - FlatRedBall.FlatRedBallServices.GraphicsOptions.SetResolution((int)(Data.ResolutionWidth * Data.Scale/ 100.0f), (int)(Data.ResolutionHeight * Data.Scale/ 100.0f)); + var width = (int)(Data.ResolutionWidth * Data.Scale / 100.0f); + var height = (int)(Data.ResolutionHeight * Data.Scale / 100.0f); + // subtract to leave room for windows borders + var maxWidth = Microsoft.Xna.Framework.Graphics.GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width - 6; + var maxHeight = Microsoft.Xna.Framework.Graphics.GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height - 28; + width = System.Math.Min(width, maxWidth); + height = System.Math.Min(height, maxHeight); + FlatRedBall.FlatRedBallServices.GraphicsOptions.SetResolution(width, height); } #elif IOS || ANDROID FlatRedBall.FlatRedBallServices.GraphicsOptions.SetFullScreen(FlatRedBall.FlatRedBallServices.GraphicsOptions.ResolutionWidth, FlatRedBall.FlatRedBallServices.GraphicsOptions.ResolutionHeight); @@ -95,8 +102,8 @@ internal static void ResetWindow () } else { - FlatRedBall.FlatRedBallServices.GraphicsOptions.SetResolution((int)(Data.ResolutionWidth * Data.Scale/ 100.0f), (int)(Data.ResolutionHeight * Data.Scale/ 100.0f)); - var newWindowSize = new Windows.Foundation.Size((int)(Data.ResolutionWidth * Data.Scale/ 100.0f), (int)(Data.ResolutionHeight * Data.Scale/ 100.0f)); + FlatRedBall.FlatRedBallServices.GraphicsOptions.SetResolution(Data.ResolutionWidth, Data.ResolutionHeight); + var newWindowSize = new Windows.Foundation.Size(Data.ResolutionWidth, Data.ResolutionHeight); Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().TryResizeView(newWindowSize); } #endif diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileEntities/TileEntityInstantiator.cs b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileEntities/TileEntityInstantiator.cs index 63d941360..eca1d884e 100644 --- a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileEntities/TileEntityInstantiator.cs +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileEntities/TileEntityInstantiator.cs @@ -525,7 +525,9 @@ private static IEntityFactory GetFactory(string entityType) var methodInfo = type.GetMethod("CreateNew", new[] { typeof(Layer), typeof(float), typeof(float) }); var returntypeString = methodInfo.ReturnType.Name; - return entityType == returntypeString || entityType.EndsWith("\\" + returntypeString); + return entityType == returntypeString || + entityType.EndsWith("\\" + returntypeString) || + entityType.EndsWith("/" + returntypeString); }); return factory; } diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileGraphics/LayeredTileMap.cs b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileGraphics/LayeredTileMap.cs index 14b44a6b2..b0da6d3db 100644 --- a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileGraphics/LayeredTileMap.cs +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileGraphics/LayeredTileMap.cs @@ -579,8 +579,6 @@ private static void AddTileShapeCollections(LayeredTileMap layeredTileMap, Tiled { var allTilesets = tms.Tilesets; - Dictionary hasShapesDictionary = new Dictionary(); - Dictionary nameCollisionPairs = new Dictionary(); @@ -590,32 +588,13 @@ private static void AddTileShapeCollections(LayeredTileMap layeredTileMap, Tiled // Currently we only support 1 tileset per layer, so we'll find the tileset for this layer var firstNonZero = layer.data[0].tiles.FirstOrDefault(item => item != 0); + TMXGlueLib.Tileset tileset = null; + if (firstNonZero != 0) { - var tileset = tms.GetTilesetForGid(firstNonZero); - - if (tileset != null) - { - bool hasShapes; - if (hasShapesDictionary.ContainsKey(tileset)) - { - hasShapes = hasShapesDictionary[tileset]; - } - else - { - // We don't know if this tileset has shapes yet, so let's figure it out: - hasShapes = tileset.Tiles.Any(item => item.Objects?.@object?.Length > 0); - - hasShapesDictionary[tileset] = hasShapes; - } - - if (hasShapes) - { - AddTileShapeCollectionForLayer(layer, nameCollisionPairs, tileset, tms.tilewidth, i); - - } - } + tileset = tms.GetTilesetForGid(firstNonZero); } + AddTileShapeCollectionForLayer(layer, nameCollisionPairs, tileset, tms.tilewidth, i); } foreach (var item in nameCollisionPairs.Values) { @@ -663,8 +642,11 @@ private static void AddTileShapeCollectionForLayer(TMXGlueLib.MapLayer layer, Di bool sortOnY = layer.height > layer.width; + var collection = GetOrAddTileShapeCollection(layer.Name, collisionDictionary); - foreach (var tilesetTile in tileset.Tiles.Where(item => item.Objects?.@object?.Length > 0)) + if(tileset != null) + { + foreach (var tilesetTile in tileset.Tiles.Where(item => item.Objects?.@object?.Length > 0)) { var tilesetTileGid = tilesetTile.id + tileset.Firstgid; foreach (var tilesetObject in tilesetTile.Objects.@object) @@ -673,7 +655,6 @@ private static void AddTileShapeCollectionForLayer(TMXGlueLib.MapLayer layer, Di TiledMapToShapeCollectionConverter.ConvertTiledObjectToFrbShape(tilesetObject, out polygon, out rectangle, out circle); if (rectangle != null) { - TileCollisions.TileShapeCollection collection = null; rectangle.Z = z; if (sortOnY) { @@ -681,7 +662,7 @@ private static void AddTileShapeCollectionForLayer(TMXGlueLib.MapLayer layer, Di { for (int x = 0; x < layer.width; x++) { - AddRectangleCloneAtXY(layer, tileDimension, rectangle, tiles, tilesetTileGid, x, y, collisionDictionary, ref collection); + AddRectangleCloneAtXY(layer, tileDimension, rectangle, tiles, tilesetTileGid, x, y, collection); } } } @@ -691,14 +672,13 @@ private static void AddTileShapeCollectionForLayer(TMXGlueLib.MapLayer layer, Di { for (int y = 0; y < layer.height; y++) { - AddRectangleCloneAtXY(layer, tileDimension, rectangle, tiles, tilesetTileGid, x, y, collisionDictionary, ref collection); + AddRectangleCloneAtXY(layer, tileDimension, rectangle, tiles, tilesetTileGid, x, y, collection); } } } } else if (polygon != null) { - TileCollisions.TileShapeCollection collection = null; // For tile polygons we want them to be centered on the tile. // To do this, we shift all points by its position: @@ -720,7 +700,8 @@ private static void AddTileShapeCollectionForLayer(TMXGlueLib.MapLayer layer, Di { for (int x = 0; x < layer.width; x++) { - AddPolygonCloneAtXY(layer, tileDimension, polygon, tiles, tilesetTileGid, x, y, collisionDictionary, ref collection); + AddPolygonCloneAtXY(layer, tileDimension, polygon, tiles, tilesetTileGid, x, y, collection); + } } } @@ -730,7 +711,7 @@ private static void AddTileShapeCollectionForLayer(TMXGlueLib.MapLayer layer, Di { for (int y = 0; y < layer.height; y++) { - AddPolygonCloneAtXY(layer, tileDimension, polygon, tiles, tilesetTileGid, x, y, collisionDictionary, ref collection); + AddPolygonCloneAtXY(layer, tileDimension, polygon, tiles, tilesetTileGid, x, y, collection); } } } @@ -742,20 +723,17 @@ private static void AddTileShapeCollectionForLayer(TMXGlueLib.MapLayer layer, Di } } } + } } private static void AddPolygonCloneAtXY(MapLayer layer, float tileDimension, Polygon polygon, List tiles, long tilesetTileGid, int x, int y, - Dictionary dictionary, ref TileCollisions.TileShapeCollection collectionForThisName) + TileCollisions.TileShapeCollection collectionForThisName) { var i = y * layer.width + x; if (tiles[i] == tilesetTileGid) { - if (collectionForThisName == null) - { - collectionForThisName = GetOrAddTileShapeCollection(polygon.Name ?? layer.Name, dictionary); - } int xIndex = i % layer.width; // intentional int division int yIndex = i / layer.width; @@ -770,18 +748,15 @@ private static void AddTileShapeCollectionForLayer(TMXGlueLib.MapLayer layer, Di } private static void AddRectangleCloneAtXY(MapLayer layer, float tileDimension, AxisAlignedRectangle rectangle, List tiles, long tilesetTileGid, int x, int y, - Dictionary dictionary, ref TileCollisions.TileShapeCollection collectionForThisName) + TileCollisions.TileShapeCollection collectionForThisName) { + var i = y * layer.width + x; - var stripedId = tiles[i] & 0x0fffffff; + var strippedId = tiles[i] & 0x0fffffff; - if (stripedId == tilesetTileGid) + if (strippedId == tilesetTileGid) { - if (collectionForThisName == null) - { - collectionForThisName = GetOrAddTileShapeCollection(rectangle.Name ?? layer.Name, dictionary); - } float xIndex = i % layer.width; // intentional int division @@ -790,8 +765,12 @@ private static void AddTileShapeCollectionForLayer(TMXGlueLib.MapLayer layer, Di var cloned = rectangle.Clone(); // Offset by .5 since polygons are positioned by their center, tiles by top left - cloned.X = (xIndex + .5f) * tileDimension; - cloned.Y = -(yIndex + .5f) * tileDimension; + //cloned.X = (xIndex + .5f) * tileDimension; + //cloned.Y = -(yIndex + .5f) * tileDimension; + // Actually use the X and Y to get the top left, then use the actual rectangle's X and Y values so that + // its offset applies: + cloned.X = rectangle.X + (xIndex) * tileDimension; + cloned.Y = rectangle.Y - (yIndex) * tileDimension; collectionForThisName.Rectangles.Add(cloned); diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileGraphics/MapDrawableBatch.cs b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileGraphics/MapDrawableBatch.cs index 232ee8f69..f71548e2f 100644 --- a/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileGraphics/MapDrawableBatch.cs +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProject/TileGraphics/MapDrawableBatch.cs @@ -924,7 +924,8 @@ public void Draw(Camera camera) FlatRedBallServices.GraphicsOptions.TextureFilter = this.TextureFilter.Value; } TextureAddressMode oldTextureAddressMode; - Effect effectTouse = PrepareRenderingStates(camera, out oldTextureAddressMode); + FlatRedBall.Graphics.BlendOperation oldBlendOp; + Effect effectTouse = PrepareRenderingStates(camera, out oldTextureAddressMode, out oldBlendOp); foreach (EffectPass pass in effectTouse.CurrentTechnique.Passes) { @@ -949,6 +950,8 @@ public void Draw(Camera camera) } Renderer.TextureAddressMode = oldTextureAddressMode; + FlatRedBall.Graphics.Renderer.BlendOperation = oldBlendOp; + if (ZBuffered) { FlatRedBallServices.GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; @@ -960,12 +963,12 @@ public void Draw(Camera camera) } } - private Effect PrepareRenderingStates(Camera camera, out TextureAddressMode oldTextureAddressMode) + private Effect PrepareRenderingStates(Camera camera, out TextureAddressMode oldTextureAddressMode, out FlatRedBall.Graphics.BlendOperation oldBlendOperation) { // Set graphics states FlatRedBallServices.GraphicsDevice.RasterizerState = RasterizerState.CullNone; - var oldBlendOp = FlatRedBall.Graphics.Renderer.BlendOperation; + oldBlendOperation = FlatRedBall.Graphics.Renderer.BlendOperation; #if TILEMAPS_ALPHA_AND_COLOR FlatRedBall.Graphics.Renderer.BlendOperation = BlendOperation.Regular; @@ -1010,10 +1013,7 @@ private Effect PrepareRenderingStates(Camera camera, out TextureAddressMode oldT // on non-power-of-two textures. oldTextureAddressMode = Renderer.TextureAddressMode; Renderer.TextureAddressMode = TextureAddressMode.Clamp; - - - FlatRedBall.Graphics.Renderer.BlendOperation = oldBlendOp; - + return effectTouse; } diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/GlueTestProjectContent.contentproj b/Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/GlueTestProjectContent.contentproj index 972571f7b..dec9c07c4 100644 --- a/Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/GlueTestProjectContent.contentproj +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/GlueTestProjectContent.contentproj @@ -957,6 +957,10 @@ PreserveNewest TilbTest + + PreserveNewest + tilesetwithentities + PreserveNewest TmxForObjectSourceFile @@ -965,6 +969,10 @@ PreserveNewest TmxWithEmptyLayers + + PreserveNewest + TmxWithEntities + PreserveNewest TmxWithLayersWithProperties diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/Screens/TmxScreen/TilesetWithEntities.tsx b/Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/Screens/TmxScreen/TilesetWithEntities.tsx new file mode 100644 index 000000000..04c6dbfab --- /dev/null +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/Screens/TmxScreen/TilesetWithEntities.tsx @@ -0,0 +1,6 @@ + + + + + + diff --git a/Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/Screens/TmxScreen/TmxWithEntities.tmx b/Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/Screens/TmxScreen/TmxWithEntities.tmx new file mode 100644 index 000000000..423a894d6 --- /dev/null +++ b/Tests/GlueTestProject/GlueTestProject/GlueTestProjectContent/Screens/TmxScreen/TmxWithEntities.tmx @@ -0,0 +1,9 @@ + + + + + + H4sIAAAAAAAAC+3OsQkAAAjAMJ/W+/UAR8Elge6NADY51fcEAADAkQbtrRb2ABAAAA== + + +