package org.newdawn.slick; import java.io.InputStream; import org.newdawn.slick.opengl.Texture; /** * * @author Joris * @author Kevin Glass */ public class SpriteSheetCounted extends Image { /** The width of a single element in pixels */ private int tw; /** The height of a single element in pixels */ private int th; /** The margin of the image */ private int margin = 0; /** Subimages */ private Image[] subImages; /** The spacing between tiles */ private int spacing; /** The target image for this sheet */ private Image target; private int tilesAcross; private int tilesDown; /** * Create a new sprite sheet based on a image location * * @param image The image to based the sheet of * @param tw The width of the tiles on the sheet * @param th The height of the tiles on the sheet */ public SpriteSheetCounted(Image image,int tw,int th) { super(image); this.target = image; this.tw = tw; this.th = th; // call init manually since constructing from an image will have previously initialised // from incorrect values initImpl(); } /** * Create a new sprite sheet based on a image location * * @param image The image to based the sheet of * @param tw The width of the tiles on the sheet * @param th The height of the tiles on the sheet * @param spacing The spacing between tiles * @param margin The magrin around the tiles */ public SpriteSheetCounted(Image image,int tw,int th,int spacing,int margin) { super(image); this.target = image; this.tw = tw; this.th = th; this.spacing = spacing; this.margin = margin; // call init manually since constructing from an image will have previously initialised // from incorrect values initImpl(); } /** * Create a new sprite sheet based on a image location * * @param image The image to based the sheet of * @param tw The width of the tiles on the sheet * @param th The height of the tiles on the sheet * @param spacing The spacing between tiles */ public SpriteSheetCounted(Image image,int tw,int th,int spacing) { this(image,tw,th,spacing,0); } /** * Create a new sprite sheet based on a image location * * @param ref The location of the sprite sheet to load * @param tw The width of the tiles on the sheet * @param th The height of the tiles on the sheet * @param spacing The spacing between tiles * @throws SlickException Indicates a failure to load the image */ public SpriteSheetCounted(String ref,int tw,int th, int spacing) throws SlickException { this(ref,tw,th,null,spacing); } /** * Create a new sprite sheet based on a image location * * @param ref The location of the sprite sheet to load * @param tw The width of the tiles on the sheet * @param th The height of the tiles on the sheet * @throws SlickException Indicates a failure to load the image */ public SpriteSheetCounted(String ref,int tw,int th) throws SlickException { this(ref,tw,th,null); } /** * Create a new sprite sheet based on a image location * * @param ref The location of the sprite sheet to load * @param tw The width of the tiles on the sheet * @param th The height of the tiles on the sheet * @param col The colour to treat as transparent * @throws SlickException Indicates a failure to load the image */ public SpriteSheetCounted(String ref,int tw,int th, Color col) throws SlickException { this(ref, tw, th, col, 0); } /** * Create a new sprite sheet based on a image location * * @param ref The location of the sprite sheet to load * @param tw The width of the tiles on the sheet * @param th The height of the tiles on the sheet * @param col The colour to treat as transparent * @param spacing The spacing between tiles * @throws SlickException Indicates a failure to load the image */ public SpriteSheetCounted(String ref,int tw,int th, Color col, int spacing) throws SlickException { super(ref, false, FILTER_NEAREST, col); this.target = this; this.tw = tw; this.th = th; this.spacing = spacing; } /** * Create a new sprite sheet based on a image location * * @param name The name to give to the image in the image cache * @param ref The stream from which we can load the image * @param tw The width of the tiles on the sheet * @param th The height of the tiles on the sheet * @throws SlickException Indicates a failure to load the image */ public SpriteSheetCounted(String name, InputStream ref,int tw,int th) throws SlickException { super(ref,name,false); this.target = this; this.tw = tw; this.th = th; } /** * @see org.newdawn.slick.Image#initImpl() */ @Override protected void initImpl() { if (subImages != null) { return; } tilesAcross = ((getWidth()-(margin*2) - tw) / (tw + spacing)) + 1; tilesDown = ((getHeight()-(margin*2) - th) / (th + spacing)) + 1; if ((getHeight() - th) % (th+spacing) != 0) { tilesDown++; } subImages = new Image[tilesAcross * tilesDown]; int i = 0; for (int y=0;y<tilesDown;y++) { for (int x=0;x<tilesAcross;x++) { subImages[i++] = getSprite(x,y); } } } /** * Get the sub image cached in this sprite sheet * * @param tile The position in tiles of the image to get * @return The subimage at that location on the sheet */ public Image getSubImage(int tile) { init(); if ((tile < 0) || (tile >= subImages.length)) { throw new RuntimeException("SubImage out of sheet bounds: "+tile); } return subImages[tile]; } /** * Get a sprite (new Image) at a particular cell on the sprite sheet * * @param x The x position of the cell on the sprite sheet * @param y The y position of the cell on the sprite sheet * @return The single image from the sprite sheet */ public Image getSprite(int x, int y) { target.init(); initImpl(); if ((x < 0) || (x >= tilesAcross)) { throw new RuntimeException("SubImage out of sheet bounds: "+x+","+y); } if ((y < 0) || (y >= tilesDown)) { throw new RuntimeException("SubImage out of sheet bounds: "+x+","+y); } return target.getSubImage(x*(tw+spacing) + margin, y*(th+spacing) + margin,tw,th); } /** * Get the number of sprites across the sheet * * @return The number of sprites across the sheet */ public int getHorizontalCount() { target.init(); initImpl(); return this.tilesAcross; } /** * Get the number of sprites down the sheet * * @return The number of sprite down the sheet */ public int getVerticalCount() { target.init(); initImpl(); return this.tilesDown; } public int getTilesCount() { target.init(); initImpl(); return this.subImages.length; } /** * Render a sprite when this sprite sheet is in use. * * @see #startUse() * @see #endUse() * * @param x The x position to render the sprite at * @param y The y position to render the sprite at * @param tile The location of the cell to render */ public void renderInUse(int x,int y, int tile) { subImages[tile].drawEmbedded(x, y, tw, th); } /** * @see org.newdawn.slick.Image#endUse() */ @Override public void endUse() { if (target == this) { super.endUse(); return; } target.endUse(); } /** * @see org.newdawn.slick.Image#startUse() */ @Override public void startUse() { if (target == this) { super.startUse(); return; } target.startUse(); } /** * @see org.newdawn.slick.Image#setTexture(org.newdawn.slick.opengl.Texture) */ @Override public void setTexture(Texture texture) { if (target == this) { super.setTexture(texture); return; } target.setTexture(texture); } }