package org.newdawn.slick; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.HashMap; import org.newdawn.slick.util.Log; import org.newdawn.slick.util.ResourceLoader; /** * A sprite sheet packed and defined by the Pacific Software Image Packer available * from: * * http://homepage.ntlworld.com/config/imagepacker/ * * @author kevin */ public class PackedSpriteSheet { /** The image loaded for the sheet */ private Image image; /** The base path where the image is expected to be found based on the original definition file */ private String basePath; /** The section definitions */ private HashMap sections = new HashMap(); /** The filter used when loading the image */ private int filter = Image.FILTER_NEAREST; /** * Create a new packed sprite sheet based on a ImagePacker definition file * * @param def The location of the definition file to read * @throws SlickException Indicates a failure to read the definition file */ public PackedSpriteSheet(String def) throws SlickException { this(def, null); } /** * Create a new packed sprite sheet based on a ImagePacker definition file * * @param def The location of the definition file to read * @param trans The color to be treated as transparent * @throws SlickException Indicates a failure to read the definition file */ public PackedSpriteSheet(String def, Color trans) throws SlickException { def = def.replace('\\', '/'); basePath = def.substring(0,def.lastIndexOf("/")+1); loadDefinition(def, trans); } /** * Create a new packed sprite sheet based on a ImagePacker definition file * * @param def The location of the definition file to read * @param filter The image filter to use when loading the packed sprite image * @throws SlickException Indicates a failure to read the definition file */ public PackedSpriteSheet(String def, int filter) throws SlickException { this(def, filter, null); } /** * Create a new packed sprite sheet based on a ImagePacker definition file * * @param def The location of the definition file to read * @param filter The image filter to use when loading the packed sprite image * @param trans The color to be treated as transparent * @throws SlickException Indicates a failure to read the definition file */ public PackedSpriteSheet(String def, int filter, Color trans) throws SlickException { this.filter = filter; def = def.replace('\\', '/'); basePath = def.substring(0,def.lastIndexOf("/")+1); loadDefinition(def, trans); } /** * Get the full image contaning all the sprites/sections * * @return The full image containing all the sprites/sections */ public Image getFullImage() { return image; } /** * Get a single named sprite from the sheet * * @param name The name of the sprite to retrieve * @return The sprite requested (image of) */ public Image getSprite(String name) { Section section = (Section) sections.get(name); if (section == null) { throw new RuntimeException("Unknown sprite from packed sheet: "+name); } return image.getSubImage(section.x, section.y, section.width, section.height); } /** * Get a sprite sheet that has been packed into the greater image * * @param name The name of the sprite sheet to retrieve * @return The sprite sheet from the packed sheet */ public SpriteSheet getSpriteSheet(String name) { Image image = getSprite(name); Section section = (Section) sections.get(name); return new SpriteSheet(image, section.width / section.tilesx, section.height / section.tilesy); } /** * Load the definition file and parse each of the sections * * @param def The location of the definitions file * @param trans The color to be treated as transparent * @throws SlickException Indicates a failure to read or parse the definitions file * or referenced image. */ private void loadDefinition(String def, Color trans) throws SlickException { BufferedReader reader = new BufferedReader(new InputStreamReader(ResourceLoader.getResourceAsStream(def))); try { image = new Image(basePath+reader.readLine(), false, filter, trans); while (reader.ready()) { if (reader.readLine() == null) { break; } Section sect = new Section(reader); sections.put(sect.name, sect); if (reader.readLine() == null) { break; } } } catch (Exception e) { Log.error(e); throw new SlickException("Failed to process definitions file - invalid format?", e); } } /** * A single section defined within the packed sheet * * @author kevin */ private class Section { /** The x position of the section */ public int x; /** The y position of the section */ public int y; /** The width of the section */ public int width; /** The height of the section */ public int height; /** The number of sprites across this section */ public int tilesx; /** The number of sprites down this section */ public int tilesy; /** The name of this section */ public String name; /** * Create a new section by reading the stream provided * * @param reader The reader from which the definition can be read * @throws IOException Indicates a failure toread the provided stream */ public Section(BufferedReader reader) throws IOException { name = reader.readLine().trim(); x = Integer.parseInt(reader.readLine().trim()); y = Integer.parseInt(reader.readLine().trim()); width = Integer.parseInt(reader.readLine().trim()); height = Integer.parseInt(reader.readLine().trim()); tilesx = Integer.parseInt(reader.readLine().trim()); tilesy = Integer.parseInt(reader.readLine().trim()); reader.readLine().trim(); reader.readLine().trim(); tilesx = Math.max(1,tilesx); tilesy = Math.max(1,tilesy); } } }