package loon.action.map.tmx; import loon.LSystem; import loon.action.map.Field2D; import loon.action.map.tmx.renderers.TMXHexagonalMapRenderer; import loon.action.map.tmx.renderers.TMXIsometricMapRenderer; import loon.action.map.tmx.renderers.TMXMapRenderer; import loon.action.map.tmx.renderers.TMXOrthogonalMapRenderer; import loon.action.map.tmx.renderers.TMXStaggeredMapRenderer; import loon.canvas.LColor; import loon.utils.TArray; import loon.utils.xml.XMLDocument; import loon.utils.xml.XMLElement; import loon.utils.xml.XMLParser; public class TMXMap { /** * 该TiledMap类的渲染(瓦片显示方向)模式 */ public enum Orientation { ORTHOGONAL, ISOMETRIC, STAGGERED, HEXAGONAL } /** * 该TiledMap类的渲染呈现顺序 */ public enum RenderOrder { RIGHT_DOWN, RIGHT_UP, LEFT_DOWN, LEFT_UP } /** * 此地图的交错轴(地图不是六角形时生效) */ public enum StaggerAxis { AXIS_X, AXIS_Y, NONE } /** * 此地图的错开模式。适用于六边形和等距交错地图。 */ public enum StaggerIndex { NONE, EVEN, ODD } public static final long FLIPPED_HORIZONTALLY_FLAG = 0x80000000; public static final long FLIPPED_VERTICALLY_FLAG = 0x40000000; public static final long FLIPPED_DIAGONALLY_FLAG = 0x20000000; private String filePath; private String tilesLocation; private LColor backgroundColor; private double version; private Orientation orientation; private RenderOrder renderOrder; private StaggerAxis staggerAxis; private StaggerIndex staggerIndex; private int width; private int height; private int tileWidth; private int tileHeight; private int nextObjectID; private int hexSideLength; private TArray<TMXMapLayer> layers; private TArray<TMXTileLayer> tileLayers; private TArray<TMXImageLayer> imageLayers; private TArray<TMXObjectLayer> objectLayers; private TArray<TMXTileSet> tileSets; private TMXProperties properties; public TMXMap(String filePath, String tilesLocation) { version = 1.0f; layers = new TArray<TMXMapLayer>(); tileLayers = new TArray<TMXTileLayer>(); imageLayers = new TArray<TMXImageLayer>(); objectLayers = new TArray<TMXObjectLayer>(); tileSets = new TArray<TMXTileSet>(); properties = new TMXProperties(); orientation = Orientation.ORTHOGONAL; renderOrder = RenderOrder.LEFT_UP; staggerAxis = StaggerAxis.NONE; staggerIndex = StaggerIndex.NONE; backgroundColor = new LColor(LColor.TRANSPARENT); this.filePath = filePath; this.tilesLocation = tilesLocation; XMLDocument doc = XMLParser.parse(filePath); XMLElement docElement = doc.getRoot(); if (!docElement.getName().equals("map")) { throw LSystem.runThrow( "Invalid TMX map file. The first child must be a <map> element."); } parse(docElement, tilesLocation); } /** * 返回一个tmx的具体渲染对象(此对象为Sprite,可以直接插入Screen,如普通Sprite同样操作) * * @return */ public TMXMapRenderer getMapRenderer() { switch (this.orientation) { case ISOMETRIC: return new TMXIsometricMapRenderer(this); case HEXAGONAL: return new TMXHexagonalMapRenderer(this); case STAGGERED: return new TMXStaggeredMapRenderer(this); default: return new TMXOrthogonalMapRenderer(this); } } public Orientation getOrientation() { return orientation; } public RenderOrder getRenderOrder() { return renderOrder; } public StaggerAxis getStaggerAxis() { return staggerAxis; } public StaggerIndex getStaggerIndex() { return staggerIndex; } public String getFilePath() { return filePath; } public LColor getBackgroundColor() { return backgroundColor; } public double getVersion() { return version; } public int getWidth() { return width; } public int getHeight() { return height; } public int getTileWidth() { return tileWidth; } public int getTileHeight() { return tileHeight; } public int getNextObjectID() { return nextObjectID; } public int getHexSideLength() { return hexSideLength; } public TMXMapLayer getLayer(int index) { return layers.get(index); } public int getNumLayers() { return layers.size; } public TArray<TMXMapLayer> getLayers() { return layers; } public TMXTileLayer getTileLayer(int index) { return tileLayers.get(index); } public int getNumTileLayers() { return tileLayers.size; } public TArray<TMXTileLayer> getTileLayers() { return tileLayers; } public TMXObjectLayer getObjectLayer(int index) { return objectLayers.get(index); } public int getNumObjectLayers() { return objectLayers.size; } public TArray<TMXObjectLayer> getObjectLayers() { return objectLayers; } public TMXImageLayer getImageLayer(int index) { return imageLayers.get(index); } public int getNumImageLayers() { return imageLayers.size; } public TArray<TMXImageLayer> getImageLayers() { return imageLayers; } public int findTileSetIndex(int gid) { gid &= ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG); for (int i = getNumTileSets() - 1; i >= 0; i--) { if (gid >= getTileset(i).getFirstGID()) { return i; } } return -1; } public TMXTileSet findTileset(int gid) { for (int i = getNumTileSets() - 1; i >= 0; i--) { if (gid >= getTileset(i).getFirstGID()) return getTileset(i); } return null; } public TMXTileSet getTileset(int index) { return tileSets.get(index); } public int getNumTileSets() { return tileSets.size; } public TArray<TMXTileSet> getTileSets() { return tileSets; } public TMXProperties getProperties() { return properties; } private void parse(XMLElement element, String tilesLocation) { version = element.getDoubleAttribute("version", 0); width = element.getIntAttribute("width", 0); height = element.getIntAttribute("height", 0); tileWidth = element.getIntAttribute("tilewidth", 0); tileHeight = element.getIntAttribute("tileheight", 0); nextObjectID = element.getIntAttribute("nextobjectid", 0); if (element.hasAttribute("background")) { String hexColor = element.getAttribute("background", LColor.white.toString()).trim(); if (hexColor.startsWith("#")) { hexColor = hexColor.substring(1); } backgroundColor = new LColor(Integer.parseInt(hexColor, 16)); } orientation = Orientation .valueOf(element.getAttribute("orientation", "ORTHOGONAL") .trim().toUpperCase()); if (element.hasAttribute("renderorder")) { switch (element.getAttribute("renderorder", "").trim() .toLowerCase()) { case "right-down": renderOrder = RenderOrder.RIGHT_DOWN; break; case "right-up": renderOrder = RenderOrder.RIGHT_UP; break; case "left-down": renderOrder = RenderOrder.LEFT_DOWN; break; case "left-up": renderOrder = RenderOrder.LEFT_UP; break; } } if (element.hasAttribute("staggeraxis")) { switch (element.getAttribute("staggeraxis", "RIGHT_DOWN").trim() .toLowerCase()) { case "x": staggerAxis = StaggerAxis.AXIS_X; break; case "y": staggerAxis = StaggerAxis.AXIS_Y; break; } } if (element.hasAttribute("staggerindex")) { switch (element.getAttribute("staggerindex", "").trim() .toLowerCase()) { case "even": staggerIndex = StaggerIndex.EVEN; break; case "odd": staggerIndex = StaggerIndex.ODD; break; } } hexSideLength = element.getIntAttribute("hexsidelength", 0); TArray<XMLElement> list = element.list(); for (XMLElement node : list) { String name = node.getName().trim().toLowerCase(); switch (name) { case "properties": properties.parse(node); break; case "tileset": TMXTileSet tileSet = new TMXTileSet(); tileSet.parse(node, tilesLocation); tileSets.add(tileSet); break; case "layer": TMXTileLayer tileLayer = new TMXTileLayer(this); tileLayer.parse(node); tileLayers.add(tileLayer); break; case "imagelayer": TMXImageLayer imageLayer = new TMXImageLayer(this); imageLayer.parse(node); imageLayers.add(imageLayer); break; case "objectgroup": TMXObjectLayer objectLayer = new TMXObjectLayer(this); objectLayer.parse(node); objectLayers.add(objectLayer); break; } } layers.addAll(tileLayers); layers.addAll(imageLayers); layers.addAll(objectLayers); } public String getTilesLocation() { return tilesLocation; } public void setTilesLocation(String tilesLocation) { this.tilesLocation = tilesLocation; } public TArray<Field2D> newGIDField2Ds() { return newField2Ds(0); } public TArray<Field2D> newTileSetIDField2Ds() { return newField2Ds(1); } public TArray<Field2D> newIDField2Ds() { return newField2Ds(2); } public TArray<Field2D> newField2Ds(int mode) { TArray<Field2D> list = new TArray<Field2D>(tileLayers.size); for (TMXTileLayer layer : tileLayers) { switch (mode) { case 0: list.add(layer.newGIDField2D()); break; case 1: list.add(layer.newTileSetIDField2D()); break; default: list.add(layer.newIDField2D()); break; } } return list; } }