diff --git a/graphics/HACKING.txt b/graphics/HACKING.txt index f666d29..57628a0 100644 --- a/graphics/HACKING.txt +++ b/graphics/HACKING.txt @@ -1,3 +1,23 @@ +=============== +The Recipe File +=============== + +The `tiles.dat' file is the recipe file for generating the tiles. +It is a plain-text file, where each line begins with a tile id, +followed by an image specification. + +The image specification consists of one or more image layers separated +by the pipe character (|). The layers are drawn in the order specified. + +A layer is a file name (excluding the .png extension), optionally followed +by @X,Y,W,H, where X,Y specify the upper-left corner of the rectangle to +draw, and W,H specify the width and height of the rectangle to draw. + + +============================== +Generating the composite image +============================== + To build a new tiles.png file, do the following: 1. Open a command-prompt, and cd to the graphics subdirectory. diff --git a/graphics/MakeTiles.java b/graphics/MakeTiles.java index f9e20bd..881dbbc 100644 --- a/graphics/MakeTiles.java +++ b/graphics/MakeTiles.java @@ -42,31 +42,42 @@ public class MakeTiles String tileImage = tileData.get(Integer.toString(i)); assert tileImage != null; - ImageRef ref = parseImageRef(tileImage); - if (!loadedImages.containsKey(ref.fileName)) { - loadedImages.put(ref.fileName, - loadImage(ref.fileName)); - } - - Image sourceImg = loadedImages.get(ref.fileName); - int srcWidth = sourceImg.getWidth(null); - int srcHeight = sourceImg.getHeight(null); - - gr.drawImage( - sourceImg, - 0, TILE_SIZE*i, - TILE_SIZE, TILE_SIZE*(i+1), - ref.offsetX, ref.offsetY, - ref.offsetX + (ref.width != 0 ? ref.width : srcWidth), - ref.offsetY + (ref.height != 0 ? ref.height : srcHeight), - null); + ImageSpec ref = parseImageSpec(tileImage); + drawTo(ref, gr, 0, TILE_SIZE*i); } ImageIO.write(buf, "png", outputFile); } - static class ImageRef + static void drawTo(ImageSpec ref, Graphics2D gr, int destX, int destY) + throws IOException { + if (ref.background != null) { + drawTo(ref.background, gr, destX, destY); + } + + if (!loadedImages.containsKey(ref.fileName)) { + loadedImages.put(ref.fileName, + loadImage(ref.fileName)); + } + + Image sourceImg = loadedImages.get(ref.fileName); + int srcWidth = sourceImg.getWidth(null); + int srcHeight = sourceImg.getHeight(null); + + gr.drawImage( + sourceImg, + destX, destY, + destX+TILE_SIZE, destY+TILE_SIZE, + ref.offsetX, ref.offsetY, + ref.offsetX + (ref.width != 0 ? ref.width : srcWidth), + ref.offsetY + (ref.height != 0 ? ref.height : srcHeight), + null); + } + + static class ImageSpec + { + ImageSpec background; String fileName; int offsetX; int offsetY; @@ -74,31 +85,39 @@ public class MakeTiles int height; } - static ImageRef parseImageRef(String s) + static ImageSpec parseImageSpec(String chain) { - ImageRef rv = new ImageRef(); + ImageSpec result = null; - String [] parts = s.split("@", 2); + for (String layerStr : chain.split("\\|")) { + + ImageSpec rv = new ImageSpec(); + rv.background = result; + result = rv; + + String [] parts = layerStr.split("@", 2); rv.fileName = parts[0]; if (parts.length >= 2) { - String offsetInfo = parts[1]; - parts = offsetInfo.split(","); - if (parts.length >= 1) { - rv.offsetX = Integer.parseInt(parts[0]); - } - if (parts.length >= 2) { - rv.offsetY = Integer.parseInt(parts[1]); - } - if (parts.length >= 3) { - rv.width = Integer.parseInt(parts[2]); - } - if (parts.length >= 4) { - rv.height = Integer.parseInt(parts[3]); - } + String offsetInfo = parts[1]; + parts = offsetInfo.split(","); + if (parts.length >= 1) { + rv.offsetX = Integer.parseInt(parts[0]); + } + if (parts.length >= 2) { + rv.offsetY = Integer.parseInt(parts[1]); + } + if (parts.length >= 3) { + rv.width = Integer.parseInt(parts[2]); + } + if (parts.length >= 4) { + rv.height = Integer.parseInt(parts[3]); + } }//endif something given after '@' in image specifier - return rv; + }//end foreach layer in image specification + + return result; } static Image loadImage(String fileName)