package sg.atom2d.tools.map; import java.awt.*; import java.awt.image.*; import javax.swing.*; /** * a Tile is simply a square of land or object on a map. Tiles have an image, a * name, and a type. They also have a number. */ public class Tile { /* Allow global disable of colorization effects on tiles */ public static boolean effects_enabled = true; BufferedImage effectImage = null; float effect_rScale; float effect_gScale; float effect_bScale; float effect_zoom; float effect_hue; float effect_sat; private int imageWidth = 0; private int imageHeight = 0; int zoomWidth, zoomHeight; String name = null; int number = -1; String type = null; String path = null; String info = null; Image image = null; public Tile(int number, String path, String name, String type) { this.type = type; this.number = number; this.name = name; this.path = path; //System.out.println("load image" + path); this.image = new ImageIcon(path).getImage(); if (image == null) { throw new RuntimeException("Could not load image" + path); } imageWidth = image.getWidth(null); imageHeight = image.getHeight(null); zoomWidth = imageWidth; zoomHeight = imageHeight; //System.out.println(imageWidth); } public Tile(int number, String path, String name, String type, String info) { this(number, path, name, type); if (info.indexOf(',') >= 0) { throw new RuntimeException("Info string cannot contain \",\" characters"); } this.info = info; } /** * Creates a shallow copy of the given tile. It shouldn't really be * necessary to reproduce a tile, as the same tile may appear more than once * in a map without causing any trouble. * */ public Tile(Tile t) { System.err.println("WARNING: Creating shallow copy of tile"); this.number = t.number; this.type = t.type; this.name = t.name; this.path = t.path; this.image = t.image; } String getImageLocation() { return path; } /** * Compare tiles. if the number is the same, return true. else return false. * */ public boolean equals(Tile t) { if (t == null) { return false; } if (this.number == t.number/* && this.name.equals(t.name) && this.type == t.type && this.image == t.image*/) { return true; } else { return false; } } static boolean areEqual(Tile t1, Tile t2) { if (t1 == null && t2 == null) { return true; } else if (t1 != null) { return t1.equals(t2); } else { return false; } } /** * creates a null tile. this tile does not render itself, and has type of * 99999, and name "noname". */ public Tile() { image = null; } /** * returns the Image that is rendered by this tile. * */ public Image getImage() { return image; } /** * returns the type of tile. */ public String getType() { return type; } /** * returns the tile's number. */ public int getNumber() { return number; } /** * returns the tile's name. */ public String getName() { return name; } public String getInfo() { return info; } public String getPath() { return path; } /** * Copies a fresh effect image, which is a zoomed version from the original. * */ void initEffectImage() { //System.out.println("Zoom is: " + effect_zoom); effectImage = new BufferedImage((int) (imageWidth * effect_zoom), (int) (imageHeight * effect_zoom), BufferedImage.TYPE_INT_ARGB); Graphics2D g = (Graphics2D) effectImage.getGraphics(); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g.drawImage(image, 0, 0, (int) (imageWidth * effect_zoom), (int) (imageHeight * effect_zoom), null, (ImageObserver) null); //effectImage.getGraphics().drawImage(image, 0, 0, (ImageObserver)null); } /** * Colourizes and zooms the image * */ void adjustRGBHS(float rScale, float gScale, float bScale, float hueOffset, float satScale, float zoom) { if (effects_enabled) { if (zoom == effect_zoom && rScale == effect_rScale && gScale == effect_gScale && bScale == effect_bScale) { return; } effect_zoom = zoom; zoomWidth = (int) (imageWidth * zoom); zoomHeight = (int) (imageHeight * zoom); initEffectImage(); float[] hsbVals = new float[3]; Color rgbVals; WritableRaster raster = effectImage.getRaster(); int pixelData[] = new int[(zoomWidth * zoomHeight * 4)]; pixelData = raster.getPixels(0, 0, zoomWidth, zoomHeight, pixelData); for (int i = 0; i < pixelData.length / 4; i++) { if (hueOffset != 0 || satScale != 1) { hsbVals = Color.RGBtoHSB(pixelData[i * 4], pixelData[i * 4 + 1], pixelData[i * 4 + 2], hsbVals); hsbVals[0] += hueOffset; hsbVals[1] *= satScale; if (hsbVals[1] > 1) { hsbVals[1] = 1; } rgbVals = new Color(Color.HSBtoRGB(hsbVals[0], hsbVals[1], hsbVals[2])); pixelData[i * 4 + 0] = rgbVals.getRed(); pixelData[i * 4 + 1] = rgbVals.getGreen(); pixelData[i * 4 + 2] = rgbVals.getBlue(); } pixelData[i * 4] = (int) (pixelData[i * 4] * rScale); if (pixelData[i * 4] > 255) { pixelData[i * 4] = 255; } pixelData[i * 4 + 1] = (int) (pixelData[i * 4 + 1] * gScale); if (pixelData[i * 4 + 1] > 255) { pixelData[i * 4 + 1] = 255; } pixelData[i * 4 + 2] = (int) (pixelData[i * 4 + 2] * bScale); if (pixelData[i * 4 + 2] > 255) { pixelData[i * 4 + 2] = 255; } } raster.setPixels(0, 0, zoomWidth, zoomHeight, pixelData); } } /** * renders the tile's image if it exists. */ public void render(Graphics g, int x, int y) { if (effects_enabled && effectImage != null) { g.drawImage(effectImage, x - zoomWidth, y - zoomHeight, null); } else if (image != null) { g.drawImage(image, x - imageWidth, y - imageHeight, null); } } }