graphics: MakeTiles: support layering two or more images together

git-svn-id: https://micropolis.googlecode.com/svn/trunk/micropolis-java@705 d9718cc8-9f43-0410-858b-315f434eb58c
This commit is contained in:
jason@long.name 2013-06-26 13:12:52 +00:00
parent 57fd5c0847
commit 2e217755a3
2 changed files with 76 additions and 37 deletions

View file

@ -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.

View file

@ -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)