TileImages: more object-oriented tile-drawing code

This commit is contained in:
Jason Long 2015-01-07 13:13:19 -05:00
parent 6c0c9203a4
commit dbdad3b37e

View file

@ -25,7 +25,6 @@ public class TileImages
final String name; final String name;
final int TILE_WIDTH; final int TILE_WIDTH;
final int TILE_HEIGHT; final int TILE_HEIGHT;
BufferedImage tileImages;
TileImage [] tileImageMap; TileImage [] tileImageMap;
Map<SpriteKind, Map<Integer, Image> > spriteImages; Map<SpriteKind, Map<Integer, Image> > spriteImages;
@ -35,6 +34,7 @@ public class TileImages
static class SimpleTileImage extends TileImage static class SimpleTileImage extends TileImage
{ {
BufferedImage srcImage;
int imageNumber; int imageNumber;
} }
@ -54,7 +54,6 @@ public class TileImages
this.TILE_WIDTH = size; this.TILE_WIDTH = size;
this.TILE_HEIGHT = size; this.TILE_HEIGHT = size;
this.tileImages = loadImage(getResourceName());
initTileImageMap(); initTileImageMap();
} }
@ -63,16 +62,22 @@ public class TileImages
return "/" + name + "/tiles.png"; return "/" + name + "/tiles.png";
} }
SimpleTileImage readSimpleImage(XMLStreamReader in) interface LoaderContext
{
BufferedImage getDefaultImage();
}
static SimpleTileImage readSimpleImage(XMLStreamReader in, LoaderContext ctx)
throws XMLStreamException throws XMLStreamException
{ {
SimpleTileImage img = new SimpleTileImage(); SimpleTileImage img = new SimpleTileImage();
String tmp = in.getAttributeValue(null, "offsetY"); String tmp = in.getAttributeValue(null, "offsetY");
img.srcImage = ctx.getDefaultImage();
img.imageNumber = tmp != null ? Integer.parseInt(tmp) : 0; img.imageNumber = tmp != null ? Integer.parseInt(tmp) : 0;
return img; return img;
} }
AnimatedTile readAnimation(XMLStreamReader in) static AnimatedTile readAnimation(XMLStreamReader in, LoaderContext ctx)
throws XMLStreamException throws XMLStreamException
{ {
ArrayList<SimpleTileImage> frames = new ArrayList<SimpleTileImage>(); ArrayList<SimpleTileImage> frames = new ArrayList<SimpleTileImage>();
@ -80,7 +85,7 @@ public class TileImages
while (in.nextTag() != XMLStreamConstants.END_ELEMENT) { while (in.nextTag() != XMLStreamConstants.END_ELEMENT) {
String tagName = in.getLocalName(); String tagName = in.getLocalName();
if (tagName.equals("frame")) { if (tagName.equals("frame")) {
frames.add(readSimpleImage(in)); frames.add(readSimpleImage(in, ctx));
} }
skipToEndElement(in); skipToEndElement(in);
} }
@ -90,6 +95,23 @@ public class TileImages
return anim; return anim;
} }
class MyLoaderContext implements LoaderContext
{
BufferedImage defImage;
MyLoaderContext()
{
String resourceName = "/" + name + "/tiles.png";
defImage = loadImage(resourceName);
}
//implements LoaderContext
public BufferedImage getDefaultImage()
{
return defImage;
}
}
void initTileImageMap() void initTileImageMap()
{ {
if (this.spriteImages != null) { if (this.spriteImages != null) {
@ -97,6 +119,8 @@ public class TileImages
return; return;
} }
LoaderContext ctx = new MyLoaderContext();
try try
{ {
@ -128,10 +152,10 @@ public class TileImages
while (in.nextTag() != XMLStreamConstants.END_ELEMENT) { while (in.nextTag() != XMLStreamConstants.END_ELEMENT) {
assert in.isStartElement(); assert in.isStartElement();
if (in.getLocalName().equals("image")) { if (in.getLocalName().equals("image")) {
img = readSimpleImage(in); img = readSimpleImage(in, ctx);
} }
else if (in.getLocalName().equals("animation")) { else if (in.getLocalName().equals("animation")) {
img = readAnimation(in); img = readAnimation(in, ctx);
} }
skipToEndElement(in); skipToEndElement(in);
} }
@ -176,16 +200,25 @@ public class TileImages
public class ImageInfo public class ImageInfo
{ {
BufferedImage srcImage;
int imageNumber; int imageNumber;
boolean animated; boolean animated;
ImageInfo(int imageNumber, boolean animated) { ImageInfo(BufferedImage srcImage, int imageNumber, boolean animated) {
this.srcImage = srcImage;
this.imageNumber = imageNumber; this.imageNumber = imageNumber;
this.animated = animated; this.animated = animated;
} }
boolean isAnimated() { return animated; } boolean isAnimated() { return animated; }
public void drawTo(Graphics gr, int destX, int destY)
{
gr.drawImage(getImage(),
destX, destY,
null);
}
public void drawToBytes(BufferedImage img, int x, int y) public void drawToBytes(BufferedImage img, int x, int y)
{ {
for (int yy = 0; yy < TILE_HEIGHT; yy++) for (int yy = 0; yy < TILE_HEIGHT; yy++)
@ -193,14 +226,14 @@ public class TileImages
for (int xx = 0; xx < TILE_WIDTH; xx++) for (int xx = 0; xx < TILE_WIDTH; xx++)
{ {
img.setRGB(x+xx,y+yy, img.setRGB(x+xx,y+yy,
tileImages.getRGB(xx,imageNumber*TILE_HEIGHT+yy)); srcImage.getRGB(xx,imageNumber*TILE_HEIGHT+yy));
} }
} }
} }
public Image getImage() public Image getImage()
{ {
return tileImages.getSubimage( return srcImage.getSubimage(
0, imageNumber*TILE_HEIGHT, 0, imageNumber*TILE_HEIGHT,
TILE_WIDTH, TILE_HEIGHT TILE_WIDTH, TILE_HEIGHT
); );
@ -221,24 +254,22 @@ public class TileImages
if (ti instanceof SimpleTileImage) { if (ti instanceof SimpleTileImage) {
final SimpleTileImage sti = (SimpleTileImage) ti; final SimpleTileImage sti = (SimpleTileImage) ti;
return new ImageInfo(sti.imageNumber, false); return new ImageInfo(sti.srcImage, sti.imageNumber, false);
} }
else if (ti instanceof AnimatedTile) { else if (ti instanceof AnimatedTile) {
final AnimatedTile anim = (AnimatedTile) ti; final AnimatedTile anim = (AnimatedTile) ti;
final SimpleTileImage sti = anim.getFrameByTime(acycle); final SimpleTileImage sti = anim.getFrameByTime(acycle);
return new ImageInfo(sti.imageNumber, true); return new ImageInfo(sti.srcImage, sti.imageNumber, true);
} }
else { else {
assert ti != null : "no image for tile "+tileNumber; throw new Error("no image for tile "+tileNumber);
assert false : "ti is a "+ti.getClass();
return new ImageInfo(0, false);
} }
} }
public Image getTileImage(int tile) public Image getTileImage(int tile)
{ {
return getTileImageInfo(tile, 0).getImage(); return getTileImageInfo(tile).getImage();
} }
public Image getSpriteImage(SpriteKind kind, int frameNumber) public Image getSpriteImage(SpriteKind kind, int frameNumber)