/** * Render a section of the tile map * * @param x The x location to render at * @param y The y location to render at * @param sx The x tile location to start rendering * @param sy The y tile location to start rendering * @param width The width of the section to render (in tiles) * @param height The height of the secton to render (in tiles) * @param lineByLine True if we should render line by line, i.e. giving us a chance to render * something else between lines (@see {@link #renderedLine(int, int, int)} */ public void render(int x, int y, int sx, int sy, int width, int height, boolean lineByLine) { switch (orientation) { case ORTHOGONAL: for (int ty = 0; ty < height; ty++) { for (int i = 0; i < layers.size(); i++) { Layer layer = (Layer) layers.get(i); layer.render(x, y, sx, sy, width, ty, lineByLine, tileWidth, tileHeight); } } break; case ISOMETRIC: renderIsometricMap(x, y, sx, sy, width, height, null, lineByLine); break; default: // log error or something } }
/** * Load a TilED map * * @param in The input stream from which to load the map * @param tileSetsLocation The location from which we can retrieve tileset images * @throws SlickException Indicates a failure to parse the map or find a tileset */ private void load(InputStream in, String tileSetsLocation) throws SlickException { tilesLocation = tileSetsLocation; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(false); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver( new EntityResolver() { public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { return new InputSource(new ByteArrayInputStream(new byte[0])); } }); Document doc = builder.parse(in); Element docElement = doc.getDocumentElement(); if (docElement.getAttribute("orientation").equals("orthogonal")) { orientation = ORTHOGONAL; } else { orientation = ISOMETRIC; } width = Integer.parseInt(docElement.getAttribute("width")); height = Integer.parseInt(docElement.getAttribute("height")); tileWidth = Integer.parseInt(docElement.getAttribute("tilewidth")); tileHeight = Integer.parseInt(docElement.getAttribute("tileheight")); // now read the map properties Element propsElement = (Element) docElement.getElementsByTagName("properties").item(0); if (propsElement != null) { NodeList properties = propsElement.getElementsByTagName("property"); if (properties != null) { props = new Properties(); for (int p = 0; p < properties.getLength(); p++) { Element propElement = (Element) properties.item(p); String name = propElement.getAttribute("name"); String value = propElement.getAttribute("value"); props.setProperty(name, value); } } } if (loadTileSets) { TileSet tileSet = null; TileSet lastSet = null; NodeList setNodes = docElement.getElementsByTagName("tileset"); for (int i = 0; i < setNodes.getLength(); i++) { Element current = (Element) setNodes.item(i); tileSet = new TileSet(this, current, !headless); tileSet.index = i; if (lastSet != null) { lastSet.setLimit(tileSet.firstGID - 1); } lastSet = tileSet; tileSets.add(tileSet); } } NodeList layerNodes = docElement.getElementsByTagName("layer"); for (int i = 0; i < layerNodes.getLength(); i++) { Element current = (Element) layerNodes.item(i); Layer layer = new Layer(this, current); layer.index = i; layers.add(layer); } // acquire object-groups NodeList objectGroupNodes = docElement.getElementsByTagName("objectgroup"); for (int i = 0; i < objectGroupNodes.getLength(); i++) { Element current = (Element) objectGroupNodes.item(i); ObjectGroup objectGroup = new ObjectGroup(current, this); objectGroup.index = i; objectGroups.add(objectGroup); } } catch (Exception e) { Log.error(e); throw new SlickException("Failed to parse tilemap", e); } }
/** * Render of isometric map renders. * * @param x The x location to render at * @param y The y location to render at * @param sx The x tile location to start rendering * @param sy The y tile location to start rendering * @param width The width of the section to render (in tiles) * @param height The height of the section to render (in tiles) * @param layer if this is null all layers are rendered, if not only the selected layer is * renderered * @param lineByLine True if we should render line by line, i.e. giving us a chance to render * something else between lines (@see {@link #renderedLine(int, int, int)} * <p>TODO: [Isometric map] Render stuff between lines, concept of line differs from ortho * maps */ protected void renderIsometricMap( int x, int y, int sx, int sy, int width, int height, Layer layer, boolean lineByLine) { ArrayList drawLayers = layers; if (layer != null) { drawLayers = new ArrayList(); drawLayers.add(layer); } int maxCount = width * height; int allCount = 0; boolean allProcessed = false; int initialLineX = x; int initialLineY = y; int startLineTileX = 0; int startLineTileY = 0; while (!allProcessed) { int currentTileX = startLineTileX; int currentTileY = startLineTileY; int currentLineX = initialLineX; int min = 0; if (height > width) min = (startLineTileY < width - 1) ? startLineTileY : (width - currentTileX < height) ? width - currentTileX - 1 : width - 1; else min = (startLineTileY < height - 1) ? startLineTileY : (width - currentTileX < height) ? width - currentTileX - 1 : height - 1; for (int burner = 0; burner <= min; currentTileX++, currentTileY--, burner++) { for (int layerIdx = 0; layerIdx < drawLayers.size(); layerIdx++) { Layer currentLayer = (Layer) drawLayers.get(layerIdx); currentLayer.render( currentLineX, initialLineY, currentTileX, currentTileY, 1, 0, lineByLine, tileWidth, tileHeight); } currentLineX += tileWidth; allCount++; } if (startLineTileY < (height - 1)) { startLineTileY += 1; initialLineX -= tileWidth / 2; initialLineY += tileHeight / 2; } else { startLineTileX += 1; initialLineX += tileWidth / 2; initialLineY += tileHeight / 2; } if (allCount >= maxCount) allProcessed = true; } }
/** * Set the global ID of a tile at specified location in the map * * @param x The x location of the tile * @param y The y location of the tile * @param layerIndex The index of the layer to set the new tileid * @param tileid The tileid to be set */ public void setTileId(int x, int y, int layerIndex, int tileid) { Layer layer = (Layer) layers.get(layerIndex); layer.setTileID(x, y, tileid); }
/** * Get the global ID of a tile at specified location in the map * * @param x The x location of the tile * @param y The y location of the tile * @param layerIndex The index of the layer to retireve the tile from * @return The global ID of the tile */ public int getTileId(int x, int y, int layerIndex) { Layer layer = (Layer) layers.get(layerIndex); return layer.getTileID(x, y); }