package tk.amberide.ide.data.res; import tk.amberide.Amber; import java.awt.*; import java.awt.image.BufferedImage; import java.util.Collection; /** * @author Tudor */ public class Tileset { private BufferedImage image; private Dimension tileSize; private int margin, spacing; private TileSprite[][] tiles; Tileset(BufferedImage image, Dimension tileSize, int margin, int spacing) { this.image = image; this.tileSize = tileSize; this.margin = margin; this.spacing = spacing; } public TileSprite getTile(int x, int y) { return tiles[x][y]; } public BufferedImage getImage() { return image; } /** * @return the tileSize */ public Dimension getTileSize() { return tileSize; } /** * @return the margin */ public int getMargin() { return margin; } /** * @return the spacing */ public int getSpacing() { return spacing; } /** * @return the tiles */ public TileSprite[][] getTiles() { return tiles; } public int getWidth() { return tiles.length; } public int getHeight() { return tiles[0].length; } public static class Parser { private Dimension tileSize; private int margin; private int spacing; public Parser(Dimension tileSize, int margin, int spacing) { assert tileSize != null && tileSize.width > 0 && tileSize.height > 0 : "invalid dimensions"; assert margin >= 0 : "margin must not be negative"; assert spacing >= 0 : "spacing must not be negative"; this.tileSize = tileSize; this.margin = margin; this.spacing = spacing; } public Tileset parse(BufferedImage img) { int tilesAcross = ((img.getWidth() - (margin * 2) - tileSize.width) / (tileSize.width + spacing)) + 2; int tilesDown = ((img.getHeight() - (margin * 2) - tileSize.height) / (tileSize.height + spacing)) + 2; if ((img.getHeight() - tileSize.height) % (tileSize.height + spacing) != 0) { tilesDown++; } Tileset out = new Tileset(img, tileSize, margin, spacing); TileSprite[][] subImages = new TileSprite[tilesAcross][tilesDown]; for (int x = 0; x < tilesAcross; x++) { for (int y = 0; y < tilesDown; y++) { subImages[x][y] = new TileSprite( new Point( x * (tileSize.width + spacing) + margin, y * (tileSize.height + spacing) + margin), tileSize, out); } } out.tiles = subImages; return out; } } public static class TileSprite { private Point start; private Dimension size; private Tileset tileset; public static final Tileset.TileSprite NULL_SPRITE = new Tileset.TileSprite(null, null, null); public TileSprite(Point start, Dimension size, Tileset tileset) { this.start = start; this.size = size; this.tileset = tileset; } public Dimension getSize() { return size; } /** * @return the start */ public Point getStart() { return start; } /** * @param start the start to set */ public void setStart(Point start) { this.start = start; } /** * @return the owner */ public Tileset getTileset() { return tileset; } /** * @param owner the owner to set */ public void setTileset(Tileset tileset) { this.tileset = tileset; } @Override public boolean equals(Object o) { if (o instanceof TileSprite) { TileSprite other = (TileSprite) o; return (other.start == null && start == null && other.size == null && size == null && other.tileset == null && tileset == null) || (other.start.equals(start) && other.size.equals(size) && other.tileset.equals(tileset)); } return false; } public String getId() { String base = null; for (Resource<Tileset> res : Amber.getResourceManager().getTilesets()) { if (tileset.equals(res.get())) { base = res.getName(); break; } } return base + "|" + tileString(this); } public static TileSprite byId(String id) { String base = id.split("\\|")[0]; Collection<Resource<Tileset>> sheets = Amber.getResourceManager().getTilesets(); for (Resource<Tileset> res : sheets) { if (res.getName().equals(base)) { Tileset sheet = res.get(); TileSprite[][] sprites = sheet.tiles; String hash = id.split("\\|")[1]; for (TileSprite[] column : sprites) { for (TileSprite sprite : column) { if (hash.equals(tileString(sprite))) { return sprite; } } } } } return null; } protected static final String tileString(TileSprite sprite) { return String.format("%s,%s,%s,%s", sprite.start.x, sprite.start.y, sprite.size.width, sprite.size.height); } } }