1 module Dgame.Graphics.TiledMap; 2 3 private { 4 import std.xml : Document, Element; 5 import std.file : read; 6 import std.conv : to; 7 8 import Dgame.Internal.Log; 9 10 import Dgame.Math.Vector2; 11 import Dgame.Math.Vector3; 12 13 import Dgame.Graphics.TileMap; 14 import Dgame.System.VertexRenderer : Target; 15 } 16 17 class TiledMap : TileMap { 18 protected: 19 override void _readTileMap() { 20 Document doc = new Document(cast(string) .read(super._filename)); 21 22 scope Vector3f[] vertices; 23 24 foreach (const Element elem; doc.elements) { 25 if (elem.tag.name == "tileset") { 26 super._tmi.source = elem.elements[0].tag.attr["source"]; 27 28 super._tmi.tileWidth = to!ubyte(elem.tag.attr["tilewidth"]); 29 super._tmi.tileHeight = to!ubyte(elem.tag.attr["tileheight"]); 30 } 31 32 if (elem.tag.name == "layer") { 33 if (!super._tmi.width) { 34 super._tmi.width = to!ushort(elem.tag.attr["width"]); 35 super._tmi.height = to!ushort(elem.tag.attr["height"]); 36 37 if (vertices.length != 0) 38 Log.error("Wrong vertice format."); 39 40 const size_t cap = super._tmi.width * super._tmi.height; 41 42 vertices.reserve(cap * 4); 43 super._tiles.reserve(cap); 44 45 debug Log.info("TiledMap: Reserve %d vertices. Get %d.", cap * 4, vertices.capacity); 46 debug Log.info("TiledMap: Reserve %d Tiles. Get %d.", cap, super._tiles.capacity); 47 } 48 49 ushort row, col; 50 foreach (const Element child; elem.elements[0].elements) { 51 const ushort gid = to!ushort(child.tag.attr["gid"]); 52 53 const ushort vx = cast(ushort)(col * super._tmi.tileWidth); 54 const ushort vy = cast(ushort)(row * super._tmi.tileHeight); 55 56 super._tiles ~= Tile(gid, [vx, vy], [col, row], elem.tag.attr["name"], ); 57 58 const float vw = super._tmi.tileWidth; 59 const float vh = super._tmi.tileHeight; 60 61 vertices ~= Vector3f(vx, vy); /// #1 62 vertices ~= Vector3f(vx + vw, vy); /// #2 63 vertices ~= Vector3f(vx, vy + vh); /// #3 64 vertices ~= Vector3f(vx + vw, vy + vh); /// #4 65 66 col++; 67 if (col >= super._tmi.width) { 68 col = 0; 69 row++; 70 } 71 } 72 } 73 } 74 75 debug Log.info("TiledMap: Needed %d vertices.", vertices.length); 76 debug Log.info("TiledMap: Needed %d Tiles.", super._tiles.length); 77 78 /// Store the map size 79 super._tmi.mapSize[0] = super._tmi.width; 80 super._tmi.mapSize[1] = super._tmi.height; 81 82 /// Adjust to real size in pixel 83 super._tmi.width *= super._tmi.tileWidth; 84 super._tmi.height *= super._tmi.tileHeight; 85 86 super._vbo.bind(Target.Vertex); 87 88 if (!super._vbo.isCurrentEmpty()) 89 super._vbo.modify(&vertices[0], vertices.length * Vector3f.sizeof); 90 else 91 super._vbo.cache(&vertices[0], vertices.length * Vector3f.sizeof); 92 93 super._vbo.unbind(); 94 95 super._loadTileset(); 96 } 97 98 public: 99 /** 100 * CTor 101 * 102 * If compress is true, only the needed Tiles are stored 103 * (which means that are new tileset is created which contains only the needed tiles) 104 * otherwise the whole tileset is taken. 105 */ 106 this(string filename, bool compress = true) { 107 super(filename, compress); 108 } 109 } 110