MakeTiles: working on support for animated tiles
This commit is contained in:
parent
de82160792
commit
41c8d68717
2 changed files with 118 additions and 16 deletions
src/micropolisj/build_tool
|
@ -9,7 +9,7 @@ import static micropolisj.XML_Helper.*;
|
||||||
class Animation extends MakeTiles.TileImage
|
class Animation extends MakeTiles.TileImage
|
||||||
{
|
{
|
||||||
static final int DEFAULT_DURATION = 125;
|
static final int DEFAULT_DURATION = 125;
|
||||||
List<AnimationFrame> frames = new ArrayList<AnimationFrame>();
|
List<Frame> frames = new ArrayList<Frame>();
|
||||||
|
|
||||||
public static Animation load(File aniFile)
|
public static Animation load(File aniFile)
|
||||||
throws IOException
|
throws IOException
|
||||||
|
@ -20,6 +20,11 @@ class Animation extends MakeTiles.TileImage
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addFrame(Frame f)
|
||||||
|
{
|
||||||
|
frames.add(f);
|
||||||
|
}
|
||||||
|
|
||||||
void load(InputStream inStream)
|
void load(InputStream inStream)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
@ -42,8 +47,8 @@ class Animation extends MakeTiles.TileImage
|
||||||
int duration = tmp != null ? Integer.parseInt(tmp) : DEFAULT_DURATION;
|
int duration = tmp != null ? Integer.parseInt(tmp) : DEFAULT_DURATION;
|
||||||
|
|
||||||
tmp = in.getElementText();
|
tmp = in.getElementText();
|
||||||
frames.add(
|
addFrame(
|
||||||
new AnimationFrame(
|
new Frame(
|
||||||
MakeTiles.parseFrameSpec(tmp),
|
MakeTiles.parseFrameSpec(tmp),
|
||||||
duration
|
duration
|
||||||
));
|
));
|
||||||
|
@ -63,12 +68,12 @@ class Animation extends MakeTiles.TileImage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class AnimationFrame
|
static class Frame
|
||||||
{
|
{
|
||||||
MakeTiles.TileImage frame;
|
MakeTiles.TileImage frame;
|
||||||
int duration;
|
int duration;
|
||||||
|
|
||||||
public AnimationFrame(MakeTiles.TileImage frame, int duration)
|
public Frame(MakeTiles.TileImage frame, int duration)
|
||||||
{
|
{
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
|
@ -76,9 +81,22 @@ class Animation extends MakeTiles.TileImage
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
|
public void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
|
||||||
{
|
{
|
||||||
if (frames.isEmpty()) { return; }
|
if (frames.isEmpty()) { return; }
|
||||||
frames.get(0).frame.drawTo(gr, destX, destY, srcX, srcY);
|
frames.get(0).frame.drawTo(gr, destX, destY, srcX, srcY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFrameEndTime(int frameTime)
|
||||||
|
{
|
||||||
|
int t = 0;
|
||||||
|
for (int i = 0; i < frames.size(); i++) {
|
||||||
|
t += frames.get(i).duration;
|
||||||
|
if (frameTime < t) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,9 +93,33 @@ public class MakeTiles
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TileImageSprite dest = new TileImageSprite();
|
TileImage dest;
|
||||||
dest.offsetY = nextOffsetY;
|
|
||||||
nextOffsetY += TILE_SIZE;
|
if (ref.getFrameEndTime(0) > 0) {
|
||||||
|
|
||||||
|
Animation ani = new Animation();
|
||||||
|
int t = 0;
|
||||||
|
int n = ref.getFrameEndTime(t);
|
||||||
|
while (n > 0) {
|
||||||
|
TileImageSprite s = new TileImageSprite();
|
||||||
|
s.offsetY = nextOffsetY;
|
||||||
|
nextOffsetY += TILE_SIZE;
|
||||||
|
|
||||||
|
Animation.Frame f = new Animation.Frame(s, n-t);
|
||||||
|
|
||||||
|
ani.addFrame(f);
|
||||||
|
|
||||||
|
t = n;
|
||||||
|
n = ref.getFrameEndTime(t);
|
||||||
|
}
|
||||||
|
dest = ani;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TileImageSprite s = new TileImageSprite();
|
||||||
|
s.offsetY = nextOffsetY;
|
||||||
|
nextOffsetY += TILE_SIZE;
|
||||||
|
dest = s;
|
||||||
|
}
|
||||||
|
|
||||||
TileMapping m = new TileMapping(tileName, ref, dest);
|
TileMapping m = new TileMapping(tileName, ref, dest);
|
||||||
mappings.add(m);
|
mappings.add(m);
|
||||||
|
@ -107,8 +131,19 @@ public class MakeTiles
|
||||||
|
|
||||||
for (TileMapping m : mappings) {
|
for (TileMapping m : mappings) {
|
||||||
|
|
||||||
TileImageSprite sprite = (TileImageSprite) m.dest;
|
assert (m.dest instanceof Animation) || (m.dest instanceof TileImageSprite);
|
||||||
m.ref.drawTo(gr, sprite.offsetX, sprite.offsetY, 0, 0);
|
|
||||||
|
if (m.dest instanceof Animation) {
|
||||||
|
Animation ani = (Animation) m.dest;
|
||||||
|
for (Animation.Frame f : ani.frames) {
|
||||||
|
TileImageSprite s = (TileImageSprite) f.frame;
|
||||||
|
m.ref.drawTo(gr, s.offsetX, s.offsetY, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TileImageSprite sprite = (TileImageSprite) m.dest;
|
||||||
|
m.ref.drawTo(gr, sprite.offsetX, sprite.offsetY, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make parent directories if necessary
|
// make parent directories if necessary
|
||||||
|
@ -139,7 +174,20 @@ public class MakeTiles
|
||||||
out.writeStartElement("tile");
|
out.writeStartElement("tile");
|
||||||
out.writeAttribute("name", m.tileName);
|
out.writeAttribute("name", m.tileName);
|
||||||
|
|
||||||
{ //assume it is a simple sprite
|
assert (m.dest instanceof Animation) || (m.dest instanceof TileImageSprite);
|
||||||
|
if (m.dest instanceof Animation) {
|
||||||
|
|
||||||
|
Animation ani = (Animation) m.dest;
|
||||||
|
out.writeStartElement("animation");
|
||||||
|
for (Animation.Frame f : ani.frames) {
|
||||||
|
TileImageSprite s = (TileImageSprite) f.frame;
|
||||||
|
out.writeStartElement("frame");
|
||||||
|
out.writeAttribute("offsetY", Integer.toString(s.offsetY / TILE_SIZE));
|
||||||
|
out.writeEndElement();
|
||||||
|
}
|
||||||
|
out.writeEndElement();
|
||||||
|
}
|
||||||
|
else { //assume it is a simple sprite
|
||||||
|
|
||||||
TileImageSprite s = (TileImageSprite ) m.dest;
|
TileImageSprite s = (TileImageSprite ) m.dest;
|
||||||
out.writeStartElement("image");
|
out.writeStartElement("image");
|
||||||
|
@ -162,7 +210,12 @@ public class MakeTiles
|
||||||
|
|
||||||
static abstract class TileImage
|
static abstract class TileImage
|
||||||
{
|
{
|
||||||
abstract void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY);
|
public abstract void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY);
|
||||||
|
/**
|
||||||
|
* @return the end-time of the animation frame identified by frameTime;
|
||||||
|
* -1 if not an animation, or if frameTime is past the end of the animation
|
||||||
|
*/
|
||||||
|
public abstract int getFrameEndTime(int frameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TileImageLayer extends TileImage
|
static class TileImageLayer extends TileImage
|
||||||
|
@ -171,13 +224,34 @@ public class MakeTiles
|
||||||
TileImage above;
|
TileImage above;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
|
public void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
|
||||||
{
|
{
|
||||||
if (below != null) {
|
if (below != null) {
|
||||||
below.drawTo(gr, destX, destY, srcX, srcY);
|
below.drawTo(gr, destX, destY, srcX, srcY);
|
||||||
}
|
}
|
||||||
above.drawTo(gr, destX, destY, srcX, srcY);
|
above.drawTo(gr, destX, destY, srcX, srcY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFrameEndTime(int frameTime)
|
||||||
|
{
|
||||||
|
if (below == null) {
|
||||||
|
return above.getFrameEndTime(frameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
int belowEnd = below.getFrameEndTime(frameTime);
|
||||||
|
int aboveEnd = above.getFrameEndTime(frameTime);
|
||||||
|
|
||||||
|
if (belowEnd < 0) {
|
||||||
|
return aboveEnd;
|
||||||
|
}
|
||||||
|
else if (aboveEnd < 0 || belowEnd < aboveEnd) {
|
||||||
|
return belowEnd;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return aboveEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TileImageSprite extends TileImage
|
static class TileImageSprite extends TileImage
|
||||||
|
@ -187,10 +261,15 @@ public class MakeTiles
|
||||||
int offsetY;
|
int offsetY;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
|
public void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
|
||||||
{
|
{
|
||||||
source.drawTo(gr, destX, destY, srcX+offsetX, srcY+offsetY);
|
source.drawTo(gr, destX, destY, srcX+offsetX, srcY+offsetY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFrameEndTime(int frameTime) {
|
||||||
|
return source.getFrameEndTime(frameTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class SourceImage extends TileImage
|
static class SourceImage extends TileImage
|
||||||
|
@ -206,7 +285,7 @@ public class MakeTiles
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
|
public void drawTo(Graphics2D gr, int destX, int destY, int srcX, int srcY)
|
||||||
{
|
{
|
||||||
srcX = srcX * basisSize / STD_SIZE;
|
srcX = srcX * basisSize / STD_SIZE;
|
||||||
srcY = srcY * basisSize / STD_SIZE;
|
srcY = srcY * basisSize / STD_SIZE;
|
||||||
|
@ -219,6 +298,11 @@ public class MakeTiles
|
||||||
srcX+basisSize, srcY+basisSize,
|
srcX+basisSize, srcY+basisSize,
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFrameEndTime(int frameTime) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TileImage parseFrameSpec(TileSpec spec)
|
static TileImage parseFrameSpec(TileSpec spec)
|
||||||
|
|
Reference in a new issue