TiledMapHelper.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. using Microsoft.Xna.Framework;
  2. namespace MonoGame.Extended.Tiled
  3. {
  4. public static class TiledMapHelper
  5. {
  6. // 4 vertices per tile
  7. public const int VerticesPerTile = 4;
  8. // 2 triangles per tile (mesh), with each triangle indexing 3 out of 4 vertices, so 6 vertices
  9. public const int IndicesPerTile = 6;
  10. // by using ushort type for indices we are limited to indexing vertices from 0 to 65535
  11. // this limits us on how many vertices can fit inside a single vertex buffer (65536 vertices)
  12. public const int MaximumVerticesPerModel = ushort.MaxValue + 1;
  13. // and thus, we know how many tiles we can fit inside a vertex or index buffer (16384 tiles)
  14. public const int MaximumTilesPerGeometryContent = MaximumVerticesPerModel / VerticesPerTile;
  15. // and thus, we also know the maximum number of indices we can fit inside a single index buffer (98304 indices)
  16. public const int MaximumIndicesPerModel = MaximumTilesPerGeometryContent * IndicesPerTile;
  17. // these optimal maximum numbers of course are not considering texture bindings which would practically lower the actual number of tiles per vertex / index buffer
  18. // thus, the reason why it is a good to have ONE giant tileset (at least per layer)
  19. internal static Rectangle GetTileSourceRectangle(int localTileIdentifier, int tileWidth, int tileHeight, int columns, int margin, int spacing)
  20. {
  21. var x = margin + localTileIdentifier % columns * (tileWidth + spacing);
  22. var y = margin + localTileIdentifier / columns * (tileHeight + spacing);
  23. return new Rectangle(x, y, tileWidth, tileHeight);
  24. }
  25. internal static Vector2 GetOrthogonalPosition(int tileX, int tileY, int tileWidth, int tileHeight)
  26. {
  27. var x = tileX * tileWidth;
  28. var y = tileY * tileHeight;
  29. return new Vector2(x, y);
  30. }
  31. internal static Vector2 GetIsometricPosition(int tileX, int tileY, int tileWidth, int tileHeight)
  32. {
  33. // You can think of an isometric Tiled map as a regular orthogonal map that is rotated -45 degrees
  34. // i.e.: the origin (0, 0) is the top tile of the diamond grid;
  35. // (mapWidth, 0) is the far right tile of the diamond grid
  36. // (0, mapHeight) is the far left tile of the diamond grid
  37. // (mapWidth, mapHeight) is the bottom tile of the diamond grid
  38. var halfTileWidth = tileWidth * 0.5f;
  39. var halfTileHeight = tileHeight * 0.5f;
  40. // -1 because we want the top the tile-diamond (top-center) to be the origin in tile space
  41. var x = (tileX - tileY - 1) * halfTileWidth;
  42. var y = (tileX + tileY) * halfTileHeight;
  43. return new Vector2(x, y);
  44. }
  45. }
  46. }