mirror of
https://github.com/OMGeeky/ATCS.git
synced 2025-12-27 14:58:55 +01:00
Added support for the new "colorfilter" map property. Due to Java2D having no correct color filter support, only the "blackXX" values can be previwed. "bw" and "invert" cannot, the performance cost was simply way too high.
527 lines
16 KiB
Java
527 lines
16 KiB
Java
/*
|
|
* Copyright 2004-2010, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
|
|
* Copyright 2004-2006, Adam Turk <aturk@biggeruniverse.com>
|
|
*
|
|
* This file is part of libtiled-java.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
* EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
package tiled.core;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Image;
|
|
import java.awt.Rectangle;
|
|
import java.awt.Toolkit;
|
|
import java.awt.image.BufferedImage;
|
|
import java.awt.image.FilteredImageSource;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.Iterator;
|
|
import java.util.Vector;
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
import tiled.util.BasicTileCutter;
|
|
import tiled.util.TileCutter;
|
|
import tiled.util.TransparentImageFilter;
|
|
|
|
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
|
|
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
|
|
|
|
/**
|
|
* todo: Update documentation
|
|
* <p>TileSet handles operations on tiles as a set, or group. It has several
|
|
* advanced internal functions aimed at reducing unnecessary data replication.
|
|
* A 'tile' is represented internally as two distinct pieces of data. The
|
|
* first and most important is a {@link Tile} object, and these are held in
|
|
* a {@link Vector}.</p>
|
|
*
|
|
* <p>The other is the tile image.</p>
|
|
*/
|
|
public class TileSet implements Iterable<Tile>
|
|
{
|
|
private String base;
|
|
final private Vector<Tile> tiles = new Vector<Tile>();
|
|
private long tilebmpFileLastModified;
|
|
private TileCutter tileCutter;
|
|
private Rectangle tileDimensions;
|
|
private int tileSpacing;
|
|
private int tileMargin;
|
|
private int tilesPerRow;
|
|
private String externalSource;
|
|
private File tilebmpFile;
|
|
private String name;
|
|
private Color transparentColor;
|
|
private Image tileSetImage;
|
|
public Spritesheet sheet = null;
|
|
public Rectangle sheetDimensions;
|
|
|
|
/**
|
|
* Default constructor
|
|
*/
|
|
public TileSet() {
|
|
tileDimensions = new Rectangle();
|
|
}
|
|
|
|
/**
|
|
* Creates a tileset from a tileset image file.
|
|
*
|
|
* @param imgFilename
|
|
* @param cutter
|
|
* @throws IOException
|
|
* @see TileSet#importTileBitmap(BufferedImage, TileCutter)
|
|
*/
|
|
public void importTileBitmap(String imgFilename, TileCutter cutter)
|
|
throws IOException
|
|
{
|
|
setTilesetImageFilename(imgFilename);
|
|
|
|
File f = new File(imgFilename);
|
|
|
|
Image image = ImageIO.read(f.getCanonicalFile());
|
|
if (image == null) {
|
|
throw new IOException("Failed to load " + tilebmpFile);
|
|
}
|
|
|
|
Toolkit tk = Toolkit.getDefaultToolkit();
|
|
|
|
if (transparentColor != null) {
|
|
int rgb = transparentColor.getRGB();
|
|
image = tk.createImage(
|
|
new FilteredImageSource(image.getSource(),
|
|
new TransparentImageFilter(rgb)));
|
|
}
|
|
|
|
BufferedImage buffered = new BufferedImage(
|
|
image.getWidth(null),
|
|
image.getHeight(null),
|
|
BufferedImage.TYPE_INT_ARGB);
|
|
buffered.getGraphics().drawImage(image, 0, 0, null);
|
|
|
|
importTileBitmap(buffered, cutter);
|
|
}
|
|
|
|
public void loadFromProject(String name, TMXMap tmxMap, int tileWidth, int tileHeight) {
|
|
sheet = tmxMap.getProject().getSpritesheet(name);
|
|
tileDimensions.width = tileWidth;
|
|
tileDimensions.height = tileHeight;
|
|
int i = 0;
|
|
Image tileImage = sheet.getImage(i);
|
|
while (tileImage != null) {
|
|
Tile tile = new Tile();
|
|
// tile.setImage(tileImage);
|
|
addNewTile(tile);
|
|
i++;
|
|
tileImage = sheet.getImage(i);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a tileset from a buffered image. Tiles are cut by the passed
|
|
* cutter.
|
|
*
|
|
* @param tileBitmap the image to be used, must not be null
|
|
* @param cutter the tile cutter, must not be null
|
|
*/
|
|
private void importTileBitmap(BufferedImage tileBitmap, TileCutter cutter)
|
|
{
|
|
assert tileBitmap != null;
|
|
assert cutter != null;
|
|
|
|
tileCutter = cutter;
|
|
tileSetImage = tileBitmap;
|
|
|
|
cutter.setImage(tileBitmap);
|
|
|
|
tileDimensions = new Rectangle(cutter.getTileDimensions());
|
|
if (cutter instanceof BasicTileCutter) {
|
|
BasicTileCutter basicTileCutter = (BasicTileCutter) cutter;
|
|
tileSpacing = basicTileCutter.getTileSpacing();
|
|
tileMargin = basicTileCutter.getTileMargin();
|
|
tilesPerRow = basicTileCutter.getTilesPerRow();
|
|
}
|
|
|
|
BufferedImage tileImage = cutter.getNextTile();
|
|
while (tileImage != null) {
|
|
Tile tile = new Tile();
|
|
tile.setImage(tileImage);
|
|
addNewTile(tile);
|
|
tileImage = cutter.getNextTile();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Refreshes a tileset from a tileset image file.
|
|
*
|
|
* @throws IOException
|
|
* @see TileSet#importTileBitmap(BufferedImage,TileCutter)
|
|
*/
|
|
private void refreshImportedTileBitmap()
|
|
throws IOException
|
|
{
|
|
String imgFilename = tilebmpFile.getPath();
|
|
|
|
Image image = ImageIO.read(new File(imgFilename));
|
|
if (image == null) {
|
|
throw new IOException("Failed to load " + tilebmpFile);
|
|
}
|
|
|
|
Toolkit tk = Toolkit.getDefaultToolkit();
|
|
|
|
if (transparentColor != null) {
|
|
int rgb = transparentColor.getRGB();
|
|
image = tk.createImage(
|
|
new FilteredImageSource(image.getSource(),
|
|
new TransparentImageFilter(rgb)));
|
|
}
|
|
|
|
BufferedImage buffered = new BufferedImage(
|
|
image.getWidth(null),
|
|
image.getHeight(null),
|
|
BufferedImage.TYPE_INT_ARGB);
|
|
buffered.getGraphics().drawImage(image, 0, 0, null);
|
|
|
|
refreshImportedTileBitmap(buffered);
|
|
}
|
|
|
|
/**
|
|
* Refreshes a tileset from a buffered image. Tiles are cut by the passed
|
|
* cutter.
|
|
*
|
|
* @param tileBitmap the image to be used, must not be null
|
|
*/
|
|
private void refreshImportedTileBitmap(BufferedImage tileBitmap) {
|
|
assert tileBitmap != null;
|
|
|
|
tileCutter.reset();
|
|
tileCutter.setImage(tileBitmap);
|
|
|
|
tileSetImage = tileBitmap;
|
|
tileDimensions = new Rectangle(tileCutter.getTileDimensions());
|
|
|
|
int id = 0;
|
|
BufferedImage tileImage = tileCutter.getNextTile();
|
|
while (tileImage != null) {
|
|
Tile tile = getTile(id);
|
|
tile.setImage(tileImage);
|
|
tileImage = tileCutter.getNextTile();
|
|
id++;
|
|
}
|
|
}
|
|
|
|
public void checkUpdate() throws IOException {
|
|
if (tilebmpFile != null &&
|
|
tilebmpFile.lastModified() > tilebmpFileLastModified)
|
|
{
|
|
refreshImportedTileBitmap();
|
|
tilebmpFileLastModified = tilebmpFile.lastModified();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the URI path of the external source of this tile set. By setting
|
|
* this, the set is implied to be external in all other operations.
|
|
*
|
|
* @param source a URI of the tileset image file
|
|
*/
|
|
public void setSource(String source) {
|
|
externalSource = source;
|
|
}
|
|
|
|
/**
|
|
* Sets the base directory for the tileset
|
|
*
|
|
* @param base a String containing the native format directory
|
|
*/
|
|
public void setBaseDir(String base) {
|
|
this.base = base;
|
|
}
|
|
|
|
/**
|
|
* Sets the filename of the tileset image. Doesn't change the tileset in
|
|
* any other way.
|
|
*
|
|
* @param name
|
|
*/
|
|
public void setTilesetImageFilename(String name) {
|
|
if (name != null) {
|
|
tilebmpFile = new File(name);
|
|
tilebmpFileLastModified = tilebmpFile.lastModified();
|
|
}
|
|
else {
|
|
tilebmpFile = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the name of this tileset.
|
|
*
|
|
* @param name the new name for this tileset
|
|
*/
|
|
public void setName(String name) {
|
|
this.name = name;
|
|
}
|
|
|
|
/**
|
|
* Sets the transparent color in the tileset image.
|
|
*
|
|
* @param color
|
|
*/
|
|
public void setTransparentColor(Color color) {
|
|
transparentColor = color;
|
|
}
|
|
|
|
/**
|
|
* Adds the tile to the set, setting the id of the tile only if the current
|
|
* value of id is -1.
|
|
*
|
|
* @param t the tile to add
|
|
* @return int The <b>local</b> id of the tile
|
|
*/
|
|
public int addTile(Tile t) {
|
|
if (t.getId() < 0)
|
|
t.setId(tiles.size());
|
|
|
|
if (tileDimensions.width < t.getWidth())
|
|
tileDimensions.width = t.getWidth();
|
|
|
|
if (tileDimensions.height < t.getHeight())
|
|
tileDimensions.height = t.getHeight();
|
|
|
|
tiles.add(t);
|
|
t.setTileSet(this);
|
|
|
|
return t.getId();
|
|
}
|
|
|
|
/**
|
|
* This method takes a new Tile object as argument, and in addition to
|
|
* the functionality of <code>addTile()</code>, sets the id of the tile
|
|
* to -1.
|
|
*
|
|
* @see TileSet#addTile(Tile)
|
|
* @param t the new tile to add.
|
|
*/
|
|
public void addNewTile(Tile t) {
|
|
t.setId(-1);
|
|
addTile(t);
|
|
}
|
|
|
|
/**
|
|
* Removes a tile from this tileset. Does not invalidate other tile
|
|
* indices. Removal is simply setting the reference at the specified
|
|
* index to <b>null</b>.
|
|
*
|
|
* @param i the index to remove
|
|
*/
|
|
public void removeTile(int i) {
|
|
tiles.set(i, null);
|
|
}
|
|
|
|
/**
|
|
* Returns the amount of tiles in this tileset.
|
|
*
|
|
* @return the amount of tiles in this tileset
|
|
*/
|
|
public int size() {
|
|
return tiles.size();
|
|
}
|
|
|
|
/**
|
|
* Returns the maximum tile id.
|
|
*
|
|
* @return the maximum tile id, or -1 when there are no tiles
|
|
*/
|
|
public int getMaxTileId() {
|
|
return tiles.size() - 1;
|
|
}
|
|
|
|
/**
|
|
* Returns an iterator over the tiles in this tileset.
|
|
*
|
|
* @return an iterator over the tiles in this tileset.
|
|
*/
|
|
public Iterator<Tile> iterator() {
|
|
return tiles.iterator();
|
|
}
|
|
|
|
/**
|
|
* Returns the width of tiles in this tileset. All tiles in a tileset
|
|
* should be the same width, and the same as the tile width of the map the
|
|
* tileset is used with.
|
|
*
|
|
* @return int - The maximum tile width
|
|
*/
|
|
public int getTileWidth() {
|
|
return tileDimensions.width;
|
|
}
|
|
|
|
/**
|
|
* Returns the tile height of tiles in this tileset. Not all tiles in a
|
|
* tileset are required to have the same height, but the height should be
|
|
* at least the tile height of the map the tileset is used with.
|
|
*
|
|
* If there are tiles with varying heights in this tileset, the returned
|
|
* height will be the maximum.
|
|
*
|
|
* @return the max height of the tiles in the set
|
|
*/
|
|
public int getTileHeight() {
|
|
return tileDimensions.height;
|
|
}
|
|
|
|
/**
|
|
* Returns the spacing between the tiles on the tileset image.
|
|
* @return the spacing in pixels between the tiles on the tileset image
|
|
*/
|
|
public int getTileSpacing() {
|
|
return tileSpacing;
|
|
}
|
|
|
|
/**
|
|
* Returns the margin around the tiles on the tileset image.
|
|
* @return the margin in pixels around the tiles on the tileset image
|
|
*/
|
|
public int getTileMargin() {
|
|
return tileMargin;
|
|
}
|
|
|
|
/**
|
|
* Returns the number of tiles per row in the original tileset image.
|
|
* @return the number of tiles per row in the original tileset image.
|
|
*/
|
|
public int getTilesPerRow() {
|
|
return tilesPerRow;
|
|
}
|
|
|
|
/**
|
|
* Gets the tile with <b>local</b> id <code>i</code>.
|
|
*
|
|
* @param i local id of tile
|
|
* @return A tile with local id <code>i</code> or <code>null</code> if no
|
|
* tile exists with that id
|
|
*/
|
|
public Tile getTile(int i) {
|
|
try {
|
|
return tiles.get(i);
|
|
} catch (ArrayIndexOutOfBoundsException a) {}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Returns the first non-null tile in the set.
|
|
*
|
|
* @return The first tile in this tileset, or <code>null</code> if none
|
|
* exists.
|
|
*/
|
|
public Tile getFirstTile() {
|
|
Tile ret = null;
|
|
int i = 0;
|
|
while (ret == null && i <= getMaxTileId()) {
|
|
ret = getTile(i);
|
|
i++;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Returns the source of this tileset.
|
|
*
|
|
* @return a filename if tileset is external or <code>null</code> if
|
|
* tileset is internal.
|
|
*/
|
|
public String getSource() {
|
|
return externalSource;
|
|
}
|
|
|
|
/**
|
|
* Returns the base directory for the tileset
|
|
*
|
|
* @return a directory in native format as given in the tileset file or tag
|
|
*/
|
|
public String getBaseDir() {
|
|
return base;
|
|
}
|
|
|
|
/**
|
|
* Returns the filename of the tileset image.
|
|
*
|
|
* @return the filename of the tileset image, or <code>null</code> if this
|
|
* tileset doesn't reference a tileset image
|
|
*/
|
|
public String getTilebmpFile() {
|
|
if (tilebmpFile != null) {
|
|
try {
|
|
return tilebmpFile.getCanonicalPath();
|
|
} catch (IOException e) {
|
|
}
|
|
} else if (sheet != null) {
|
|
try {
|
|
return sheet.spritesheetFile.getCanonicalPath();
|
|
} catch (IOException e) {}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return the name of this tileset.
|
|
*/
|
|
public String getName() {
|
|
return name;
|
|
}
|
|
|
|
/**
|
|
* Returns the transparent color of the tileset image, or <code>null</code>
|
|
* if none is set.
|
|
*
|
|
* @return Color - The transparent color of the set
|
|
*/
|
|
public Color getTransparentColor() {
|
|
return transparentColor;
|
|
}
|
|
|
|
/**
|
|
* @return the name of the tileset, and the total tiles
|
|
*/
|
|
public String toString() {
|
|
return getName() + " [" + size() + "]";
|
|
}
|
|
|
|
|
|
// TILE IMAGE CODE
|
|
|
|
/**
|
|
* Returns whether the tileset is derived from a tileset image.
|
|
*
|
|
* @return tileSetImage != null
|
|
*/
|
|
public boolean isSetFromImage() {
|
|
return tileSetImage != null;
|
|
}
|
|
|
|
public Spritesheet getSpritesheet() {
|
|
return this.sheet;
|
|
}
|
|
}
|