protected void doPerformAction() { Map map = editor.getCurrentMap(); int ret = JOptionPane.showConfirmDialog( editor.getAppFrame(), "Do you wish to merge tile images, and create a new tile set?", "Merge Tiles?", JOptionPane.YES_NO_CANCEL_OPTION); if (ret == JOptionPane.YES_OPTION) { TileMergeHelper tmh = new TileMergeHelper(map); int len = map.getTotalLayers(); // TODO: Add a dialog option: "Yes, visible only" TileLayer newLayer = tmh.merge(0, len, true); map.removeAllLayers(); map.addLayer(newLayer); newLayer.setName("Merged Layer"); map.addTileset(tmh.getSet()); editor.setCurrentLayer(0); } else if (ret == JOptionPane.NO_OPTION) { while (map.getTotalLayers() > 1) { map.mergeLayerDown(editor.getCurrentLayerIndex()); } editor.setCurrentLayer(0); } }
/** * Unlike mergeOnto, copyTo includes the null tile when merging. * * @see MapLayer#copyFrom * @see MapLayer#mergeOnto * @param other the layer to copy this layer to */ @Override public void copyTo(MapLayer other) { for (int y = bounds.y; y < bounds.y + bounds.height; y++) { for (int x = bounds.x; x < bounds.x + bounds.width; x++) { ((TileLayer) other).setTileAt(x, y, getTileAt(x, y)); } } }
@Override public void mergeOnto(MapLayer other) { for (int y = bounds.y; y < bounds.y + bounds.height; y++) { for (int x = bounds.x; x < bounds.x + bounds.width; x++) { Tile tile = getTileAt(x, y); if (tile != null) { ((TileLayer) other).setTileAt(x, y, tile); } } } }
/** * Creates a copy of this layer. * * @see Object#clone * @return a clone of this layer, as complete as possible * @exception CloneNotSupportedException */ @Override public Object clone() throws CloneNotSupportedException { TileLayer clone = (TileLayer) super.clone(); // Clone the layer data clone.map = new Tile[map.length][]; clone.tileInstanceProperties = new HashMap<Object, Properties>(); for (int i = 0; i < map.length; i++) { clone.map[i] = new Tile[map[i].length]; System.arraycopy(map[i], 0, clone.map[i], 0, map[i].length); for (int j = 0; j < map[i].length; j++) { Properties p = getTileInstancePropertiesAt(i, j); if (p != null) { Integer key = i + j * bounds.width; clone.tileInstanceProperties.put(key, (Properties) p.clone()); } } } return clone; }
/** * Removes a {@link TileSet} from the map, and removes any tiles in the set from the map layers. A * {@link MapChangedEvent} is fired when all processing is complete. * * @param tileset TileSet to remove * @throws LayerLockedException when the tileset is in use on a locked layer */ public void removeTileset(TileSet tileset) throws LayerLockedException { // Sanity check final int tilesetIndex = tilesets.indexOf(tileset); if (tilesetIndex == -1) return; // Go through the map and remove any instances of the tiles in the set Iterator<Object> tileIterator = tileset.iterator(); while (tileIterator.hasNext()) { Tile tile = (Tile) tileIterator.next(); Iterator<MapLayer> layerIterator = getLayers(); while (layerIterator.hasNext()) { MapLayer ml = (MapLayer) layerIterator.next(); if (ml instanceof TileLayer) { ((TileLayer) ml).removeTile(tile); } } } tilesets.remove(tileset); fireTilesetRemoved(tilesetIndex); }
/** * Writes this layer to an XMLWriter. This should be done <b>after</b> the first global ids for * the tilesets are determined, in order for the right gids to be written to the layer data. */ private void writeMapLayer(MapLayer l, XMLWriter w, String wp) throws IOException { Rectangle bounds = l.getBounds(); if (l instanceof ObjectGroup) { w.startElement("objectgroup"); } else { w.startElement("layer"); } w.writeAttribute("name", l.getName()); if (bounds.width != 0) { w.writeAttribute("width", bounds.width); } if (bounds.height != 0) { w.writeAttribute("height", bounds.height); } if (bounds.x != 0) { w.writeAttribute("x", bounds.x); } if (bounds.y != 0) { w.writeAttribute("y", bounds.y); } if (!l.isVisible()) { w.writeAttribute("visible", "0"); } if (l.getOpacity() < 1.0f) { w.writeAttribute("opacity", l.getOpacity()); } writeProperties(l.getProperties(), w); if (l instanceof ObjectGroup) { writeObjectGroup((ObjectGroup) l, w, wp); } else if (l instanceof TileLayer) { final TileLayer tl = (TileLayer) l; w.startElement("data"); if (ENCODE_LAYER_DATA) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStream out; w.writeAttribute("encoding", "base64"); DeflaterOutputStream dos; if (COMPRESS_LAYER_DATA) { if (Settings.LAYER_COMPRESSION_METHOD_ZLIB.equalsIgnoreCase( settings.layerCompressionMethod)) { dos = new DeflaterOutputStream(baos); } else if (Settings.LAYER_COMPRESSION_METHOD_GZIP.equalsIgnoreCase( settings.layerCompressionMethod)) { dos = new GZIPOutputStream(baos); } else { throw new IOException( "Unrecognized compression method \"" + settings.layerCompressionMethod + "\" for map layer " + l.getName()); } out = dos; w.writeAttribute("compression", settings.layerCompressionMethod); } else { out = baos; } for (int y = 0; y < l.getHeight(); y++) { for (int x = 0; x < l.getWidth(); x++) { Tile tile = tl.getTileAt(x + bounds.x, y + bounds.y); int gid = 0; if (tile != null) { gid = getGid(tile); } out.write(gid & LAST_BYTE); out.write(gid >> 8 & LAST_BYTE); out.write(gid >> 16 & LAST_BYTE); out.write(gid >> 24 & LAST_BYTE); } } if (COMPRESS_LAYER_DATA && dos != null) { dos.finish(); } w.writeCDATA(Base64.encodeToString(baos.toByteArray(), true)); } else { for (int y = 0; y < l.getHeight(); y++) { for (int x = 0; x < l.getWidth(); x++) { Tile tile = tl.getTileAt(x + bounds.x, y + bounds.y); int gid = 0; if (tile != null) { gid = getGid(tile); } w.startElement("tile"); w.writeAttribute("gid", gid); w.endElement(); } } } w.endElement(); boolean tilePropertiesElementStarted = false; for (int y = 0; y < l.getHeight(); y++) { for (int x = 0; x < l.getWidth(); x++) { Properties tip = tl.getTileInstancePropertiesAt(x, y); if (tip != null && !tip.isEmpty()) { if (!tilePropertiesElementStarted) { w.startElement("tileproperties"); tilePropertiesElementStarted = true; } w.startElement("tile"); w.writeAttribute("x", x); w.writeAttribute("y", y); writeProperties(tip, w); w.endElement(); } } } if (tilePropertiesElementStarted) { w.endElement(); } } w.endElement(); }